home *** CD-ROM | disk | FTP | other *** search
/ Creative Computers / Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso / shareware / games / uchess / src / eval.c < prev    next >
C/C++ Source or Header  |  1994-11-17  |  81KB  |  3,212 lines

  1. #define WAY4PL64 1 // for K1PK code
  2. //#define PRE4PL67 1 // go back to 4pl63/64 stuff
  3. /*
  4.  * eval.c - C source for GNU CHESS
  5.  *
  6.  * Copyright (c) 1988,1989,1990 John Stanback
  7.  * Copyright (c) 1992 Free Software Foundation
  8.  *
  9.  * This file is part of GNU CHESS.
  10.  *
  11.  * GNU Chess is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2, or (at your option)
  14.  * any later version.
  15.  *
  16.  * GNU Chess is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GNU Chess; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25. #include "gnuchess.h"
  26. #include "ataks.h"
  27. int __aligned EADD = 0;
  28. int __aligned EGET = 0;
  29. int __aligned PUTVAR = false;
  30. #ifdef CACHE
  31. struct etable __far __aligned etab[2][ETABLE];
  32. #endif
  33.  
  34. int ScoreKBNK (short winner, short king1, short king2);
  35. int ScoreKPK (short side,
  36.       short winner,
  37.       short loser,
  38.       short king1,
  39.       register short king2,
  40.       register short sq);
  41.  
  42.  
  43. extern short __aligned PCRASH,PCENTER;
  44. short __aligned QueenCheck[MAXDEPTH]; /* tom@izf.tno.nl */
  45. int __aligned myneweval=1;
  46. short int __aligned sscore[2];
  47. /* Backward pawn bonus indexed by # of attackers on the square */
  48. static const short __aligned BACKWARD[16] =
  49. {-6, -10, -15, -21, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28};
  50.  
  51. /* Bishop mobility bonus indexed by # reachable squares */
  52. static const short __aligned BMBLTY[14] =
  53. {-2, 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16, 16, 16};
  54.  
  55. /* Rook mobility bonus indexed by # reachable squares */
  56. static const short __aligned RMBLTY[15] =
  57. {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14};
  58.  
  59. /* Positional values for a dying king */
  60. static const short __aligned DyingKing[64] =
  61. {0, 8, 16, 24, 24, 16, 8, 0,
  62.  8, 32, 40, 48, 48, 40, 32, 8,
  63.  16, 40, 56, 64, 64, 56, 40, 16,
  64.  24, 48, 64, 72, 72, 64, 48, 24,
  65.  24, 48, 64, 72, 72, 64, 48, 24,
  66.  16, 40, 56, 64, 64, 56, 40, 16,
  67.  8, 32, 40, 48, 48, 40, 32, 8,
  68.  0, 8, 16, 24, 24, 16, 8, 0};
  69.  
  70. /* Isoloted pawn penalty by rank */
  71. static const short __aligned ISOLANI[8] =
  72. {-12, -16, -20, -24, -24, -20, -16, -12};
  73.  
  74. /* table for King Bishop Knight endings */
  75. static const short __aligned KBNK[64] =
  76. #ifdef PRE4PL67KBNK
  77. {99, 90, 80, 70, 60, 50, 40, 40,
  78.  90, 80, 60, 50, 40, 30, 20, 40,
  79.  80, 60, 40, 30, 20, 10, 30, 50,
  80.  70, 50, 30, 10, 0, 20, 40, 60,
  81.  60, 40, 20, 0, 10, 30, 50, 70,
  82.  50, 30, 10, 20, 30, 40, 60, 80,
  83.  40, 20, 30, 40, 50, 60, 80, 90,
  84.  40, 40, 50, 60, 70, 80, 90, 99};
  85. #else
  86. {620, 560, 500, 440, 380, 320, 260, 240,
  87.  560, 520, 460, 400, 340, 280, 230, 260,
  88.  500, 460, 320, 280, 260, 220, 280, 320,
  89.  440, 400, 280, 200, 200, 260, 340, 380,
  90.  380, 340, 260, 200, 200, 280, 400, 440,
  91.  320, 280, 220, 260, 280, 320, 460, 500,
  92.  260, 230, 280, 340, 400, 460, 520, 560,
  93.  240, 260, 320, 380, 440, 500, 560, 620};
  94. #endif
  95.  
  96. /* penalty for threats to king, indexed by number of such threats */
  97. static const short __aligned KTHRT[36] =
  98. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  99.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  100.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  101.  
  102. /* King positional bonus inopening stage */
  103. static const short __aligned KingOpening[64] =
  104. {0, 0, -4, -10, -10, -4, 0, 0,
  105.  -4, -4, -8, -12, -12, -8, -4, -4,
  106.  -12, -16, -20, -20, -20, -20, -16, -12,
  107.  -16, -20, -24, -24, -24, -24, -20, -16,
  108.  -16, -20, -24, -24, -24, -24, -20, -16,
  109.  -12, -16, -20, -20, -20, -20, -16, -12,
  110.  -4, -4, -8, -12, -12, -8, -4, -4,
  111.  0, 0, -4, -10, -10, -4, 0, 0};
  112.  
  113. /* King positional bonus in end stage */
  114. static const short __aligned KingEnding[64] =
  115. {0, 6, 12, 18, 18, 12, 6, 0,
  116.  6, 12, 18, 24, 24, 18, 12, 6,
  117.  12, 18, 24, 30, 30, 24, 18, 12,
  118.  18, 24, 30, 36, 36, 30, 24, 18,
  119.  18, 24, 30, 36, 36, 30, 24, 18,
  120.  12, 18, 24, 30, 30, 24, 18, 12,
  121.  6, 12, 18, 24, 24, 18, 12, 6,
  122.  0, 6, 12, 18, 18, 12, 6, 0};
  123.  
  124. /* Passed pawn positional bonus */
  125. static const short __aligned PassedPawn0[8] =
  126. {0, 60, 80, 120, 200, 360, 600, 800};
  127. static const short __aligned PassedPawn1[8] =
  128. {0, 30, 40, 60, 100, 180, 300, 800};
  129. static const short __aligned PassedPawn2[8] =
  130. {0, 15, 25, 35, 50, 90, 140, 800};
  131. static const short __aligned PassedPawn3[8] =
  132. {0, 5, 10, 15, 20, 30, 140, 800};
  133.  
  134. /* Knight positional bonus */
  135. static const short __aligned pknight[64] =
  136. {0, 4, 8, 10, 10, 8, 4, 0,
  137.  4, 8, 16, 20, 20, 16, 8, 4,
  138.  8, 16, 24, 28, 28, 24, 16, 8,
  139.  10, 20, 28, 32, 32, 28, 20, 10,
  140.  10, 20, 28, 32, 32, 28, 20, 10,
  141.  8, 16, 24, 28, 28, 24, 16, 8,
  142.  4, 8, 16, 20, 20, 16, 8, 4,
  143.  0, 4, 8, 10, 10, 8, 4, 0};
  144.  
  145. /* Bishop positional bonus */
  146. static const short __aligned pbishop[64] =
  147. {14, 14, 14, 14, 14, 14, 14, 14,
  148.  14, 22, 18, 18, 18, 18, 22, 14,
  149.  14, 18, 22, 22, 22, 22, 18, 14,
  150.  14, 18, 22, 22, 22, 22, 18, 14,
  151.  14, 18, 22, 22, 22, 22, 18, 14,
  152.  14, 18, 22, 22, 22, 22, 18, 14,
  153.  14, 22, 18, 18, 18, 18, 22, 14,
  154.  14, 14, 14, 14, 14, 14, 14, 14};
  155.  
  156. /* Pawn positional bonus */
  157. static const short __aligned PawnAdvance[64] =
  158. {0, 0, 0, 0, 0, 0, 0, 0,
  159.  4, 4, 4, 0, 0, 4, 4, 4,
  160.  6, 8, 2, 10, 10, 2, 8, 6,
  161.  6, 8, 12, 16, 16, 12, 8, 6,
  162.  8, 12, 16, 24, 24, 16, 12, 8,
  163.  12, 16, 24, 32, 32, 24, 16, 12,
  164.  12, 16, 24, 32, 32, 24, 16, 12,
  165.  0, 0, 0, 0, 0, 0, 0, 0};
  166. #if !defined NOSCORESPACE
  167. #ifdef BLACKAG0
  168. /* Space positional bonus */
  169. static const short __aligned SpaceBonusB[64] =
  170. {0, 0, 0, 0, 0, 0, 0, 0,
  171.  0, 0, 2, 2, 2, 2, 0, 0,
  172.  1, 1, 2, 4, 4, 2, 1, 1,
  173.  0, 0, 3, 4, 4, 3, 0, 0,
  174.  0, 0, 5, 5, 5, 5, 0, 0,
  175.  0, 0, 4, 4, 7, 7, 0, 0,
  176.  0, 0, 0, 0, 0, 0, 0, 0,
  177.  0, 0, 0, 0, 0, 0, 0, 0};
  178. #elif defined BLACKAG1
  179. /* Space positional bonus */
  180. static const short __aligned SpaceBonusB[64] =
  181. {1, 1, 1, 1, 1, 1, 1, 1,
  182.  1, 1, 2, 2, 2, 2, 1, 1,
  183.  1, 1, 2, 3, 3, 2, 1, 1,
  184.  1, 1, 2, 4, 4, 2, 1, 1,
  185.  1, 1, 3, 5, 5, 3, 1, 1,
  186.  1, 1, 3, 6, 6, 3, 1, 1,
  187.  1, 1, 3, 7, 7, 3, 1, 1,
  188.  1, 1, 1, 1, 1, 1, 1, 1};
  189. #elif defined BLACKAG2
  190. /* Space positional bonus */
  191. static const short __aligned SpaceBonusB[64] =
  192. {1, 1, 1, 1, 1, 1, 1, 1,
  193.  1, 1, 2, 2, 2, 2, 1, 1,
  194.  1, 1, 3, 3, 3, 3, 1, 1,
  195.  1, 1, 4, 4, 4, 4, 1, 1,
  196.  1, 1, 5, 6, 6, 5, 1, 1,
  197.  1, 1, 6, 7, 7, 6, 1, 1,
  198.  1, 1, 7, 8, 8, 7, 1, 1,
  199.  1, 1, 1, 1, 1, 1, 1, 1};
  200. #elif defined BLACKAG3
  201. /* Space positional bonus */
  202. static const short __aligned SpaceBonusB[64] =
  203. {0, 0, 0, 0, 0, 0, 0, 0,
  204.  0, 0, 2, 2, 2, 2, 0, 0,
  205.  0, 0, 3, 3, 3, 3, 0, 0,
  206.  0, 0, 4, 4, 4, 3, 0, 0,
  207.  0, 0, 6, 6, 4, 4, 0, 0,
  208.  0, 0, 7, 7, 5, 5, 0, 0,
  209.  0, 0, 8, 8, 7, 7, 0, 0,
  210.  0, 0, 0, 0, 0, 0, 0, 0};
  211. #elif defined BLACKAG4
  212. /* Space positional bonus */
  213. static const short __aligned SpaceBonusB[64] =
  214. {1, 1, 1, 1, 1, 1, 1, 1,
  215.  1, 1, 2, 4, 4, 2, 1, 1,
  216.  1, 1, 2, 4, 4, 2, 1, 1,
  217.  1, 1, 2, 4, 4, 2, 1, 1,
  218.  1, 1, 2, 4, 4, 2, 1, 1,
  219.  1, 1, 2, 4, 4, 2, 1, 1,
  220.  1, 1, 2, 4, 4, 2, 1, 1,
  221.  1, 1, 1, 1, 1, 1, 1, 1};
  222. #endif
  223.  
  224. #ifdef WHITEAG0
  225. /* Space positional bonus */
  226. static const short __alignedSpaceBonusW[64] =
  227. {0, 0, 0, 0, 0, 0, 0, 0,
  228.  0, 0, 5, 5, 5, 5, 0, 0,
  229.  0, 0, 3, 4, 4, 3, 0, 0,
  230.  0, 0, 2, 4, 4, 2, 0, 0,
  231.  0, 0, 1, 4, 4, 1, 0, 0,
  232.  0, 0, 1, 4, 4, 1, 0, 0,
  233.  0, 0, 1, 2, 2, 1, 0, 0,
  234.  0, 0, 0, 0, 0, 0, 0, 0};
  235. #elif defined WHITEAG1
  236. /* Space positional bonus */
  237. static const short __alignedSpaceBonusW[64] =
  238. {1, 1, 1, 1, 1, 1, 1, 1,
  239.  1, 1, 3, 7, 7, 3, 1, 1,
  240.  1, 1, 3, 6, 6, 3, 1, 1,
  241.  1, 1, 3, 5, 5, 3, 1, 1,
  242.  1, 1, 2, 4, 4, 2, 1, 1,
  243.  1, 1, 2, 3, 3, 2, 1, 1,
  244.  1, 1, 2, 2, 2, 2, 1, 1,
  245.  1, 1, 1, 1, 1, 1, 1, 1};
  246. #elif defined WHITEAG2
  247. /* Space positional bonus */
  248. static const short __alignedSpaceBonusW[64] =
  249. {1, 1, 1, 1, 1, 1, 1, 1,
  250.  1, 1, 7, 8, 8, 7, 1, 1,
  251.  1, 1, 6, 7, 7, 6, 1, 1,
  252.  1, 1, 5, 6, 6, 5, 1, 1,
  253.  1, 1, 4, 4, 4, 4, 1, 1,
  254.  1, 1, 3, 3, 3, 3, 1, 1,
  255.  1, 1, 2, 2, 2, 2, 1, 1,
  256.  1, 1, 1, 1, 1, 1, 1, 1};
  257. #elif defined WHITEAG3
  258. /* Space positional bonus */
  259. static const short __alignedSpaceBonusW[64] =
  260. {0, 0, 0, 0, 0, 0, 0, 0,
  261.  0, 0, 8, 8, 7, 7, 0, 0,
  262.  0, 0, 7, 7, 5, 5, 0, 0,
  263.  0, 0, 6, 6, 4, 4, 0, 0,
  264.  0, 0, 4, 4, 4, 3, 0, 0,
  265.  0, 0, 3, 3, 3, 3, 0, 0,
  266.  0, 0, 2, 2, 2, 2, 0, 0,
  267.  0, 0, 0, 0, 0, 0, 0, 0};
  268. #elif defined WHITEAG4
  269. /* Space positional bonus */
  270. static const short __alignedSpaceBonusW[64] =
  271. {1, 1, 1, 1, 1, 1, 1, 1,
  272.  1, 1, 2, 4, 4, 2, 1, 1,
  273.  1, 1, 2, 4, 4, 2, 1, 1,
  274.  1, 1, 2, 4, 4, 2, 1, 1,
  275.  1, 1, 2, 4, 4, 2, 1, 1,
  276.  1, 1, 2, 4, 4, 2, 1, 1,
  277.  1, 1, 2, 4, 4, 2, 1, 1,
  278.  1, 1, 1, 1, 1, 1, 1, 1};
  279. #endif
  280. #endif
  281.  
  282. short __aligned Mwpawn[64];
  283. short __aligned Mbpawn[64];
  284. short __aligned Mknight[2][64];
  285. short __aligned Mbishop[2][64];
  286. static short __aligned Mking[2][64];
  287. static short __aligned Kfield[2][64];
  288. static short __aligned c1, c2, *atk1, *atk2, *PC1, *PC2;
  289. static short __aligned atak[2][64];
  290. short __aligned emtl[2];
  291. static short __aligned PawnBonus, BishopBonus, RookBonus;
  292. static short __aligned KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  293. static short __aligned PEDRNK2B, PWEAKH, PADVNCM, PADVNCI, PAWNSHIELD, PDOUBLED, PBLOK;
  294. static short __aligned RHOPN, RHOPNX, KHOPN, KHOPNX, KSFTY;
  295. static short __aligned ATAKD, HUNGP, HUNGX, KCASTLD, KMOVD, XRAY, PINVAL;
  296. short __aligned pscore[2];
  297. short __aligned tmtl;
  298.  
  299. #ifdef CACHE
  300. inline void
  301. PutInEETable (ARGSZ int side,int score)
  302.  
  303. /*
  304.  * Store the current eval position in the transposition table.
  305.  */
  306.  
  307. {
  308.     register struct etable *ptbl;
  309.     ptbl = &etab[side][hashkey % (ETABLE)];
  310. //    if (ptbl->ehashbd == hashbd) return;
  311.     ptbl->ehashbd = hashbd;
  312.     ptbl->escore[white] = pscore[white];
  313.     ptbl->escore[black] = pscore[black];
  314.     ptbl->hung[white] = hung[white];
  315.     ptbl->hung[black] = hung[black];
  316.     ptbl->score = score;
  317. #ifndef AMIGA
  318.     memcpy ( &(ptbl->sscore), svalue, sizeof (svalue));
  319. #else
  320.     MoveMem128(svalue,&(ptbl->sscore));
  321.    /* MoveMem(svalue,&(ptbl->sscore),sizeof (svalue));*/
  322. #endif
  323. /*    bcopy (&(ptbl->sscore), svalue, sizeof (svalue)); */
  324. #if !defined CHESSTOOL && !defined XBOARD
  325.     EADD++;
  326. #endif
  327.     return;
  328. }
  329.  
  330. inline int
  331. CheckEETable (ARGSZ int side)
  332.  
  333. /* Get an evaluation from the transposition table */
  334. {
  335.     register struct etable *ptbl;
  336.     ptbl = &etab[side][hashkey % (ETABLE)];
  337.     if (hashbd == ptbl->ehashbd) return true;
  338.     return false;
  339. }
  340.  
  341. inline int
  342. ProbeEETable (short int side, short int *score)
  343.  
  344. /* Get an evaluation from the transposition table */
  345. {
  346.     register struct etable *ptbl;
  347.     ptbl = &etab[side][hashkey % (ETABLE)];
  348.     if (hashbd == ptbl->ehashbd)
  349.       {
  350.       pscore[white] = ptbl->escore[white];
  351.       pscore[black] = ptbl->escore[black];
  352. #ifndef AMIGA
  353.       memcpy (svalue, &(ptbl->sscore), sizeof (svalue));
  354. #else
  355.       MoveMem128(&(ptbl->sscore),svalue);
  356.      /* MoveMem (&(ptbl->sscore),svalue, sizeof (svalue));*/
  357. #endif
  358.       *score = ptbl->score;
  359.           hung[white] = ptbl->hung[white];
  360.           hung[black] = ptbl->hung[black];
  361. #if !defined CHESSTOOL && !defined XBOARD
  362.       EGET++;
  363. #endif
  364.       return true;
  365.       }
  366.     return false;
  367.  
  368. }
  369.  
  370. #endif
  371.  
  372.  
  373.  
  374. short dist_ (short, short, short, short);
  375. short kpkwv_ (short, short, short, short, short, short);
  376.  
  377. #ifndef PRE4PL67
  378.  
  379. short 
  380. kpkwv_ (short pf, short pr, short wf, short wr, short bf, short br)
  381. {
  382.  
  383.   /*
  384.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  385.    */
  386.  
  387.   static short wbdd, mbpf, nbpf, blpu;
  388.   short dist_ (short, short, short, short);
  389.   static short brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  390.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  391.  
  392.   ppr = ((pr == 2)?3:pr); // was ?3:0
  393.   if (pf == 1)
  394.   { if (bf == 3)
  395.     { if (pr == 7 && wf == 1 && wr == 8 && br > 6) return(0);
  396.       if (pr == 6 && wf < 4 && wr == 6 && br == 8) return(1);
  397.     }
  398.  
  399.     if (bf == 1 && br > pr) return(0);
  400.     if (pr == 7 && bf > 2) return(1);
  401.     if (bf <= 3 && br - ppr > 1) return(0);
  402.     if (wf == 1 && bf == 3 && wr - pr == 1 && br - pr == 1) return(0);
  403.   }
  404.   bq = dist_ (bf, br, pf, 8);
  405.   if (bq > 8 - ppr) return(1);
  406.   mbpf = bf - pf;
  407.   if (mbpf < 0) mbpf = -mbpf;
  408.   bpp = dist_ (bf, br, pf, ppr);
  409.   wpp = dist_ (wf, wr, pf, ppr);
  410.   if (bpp - wpp < -1 && br - pr != mbpf) return(0);
  411.   if (pf == 1 && pr <= 3 && wf <= 2 && wr == 8 && bf == 4 && br >= 7) return(1);
  412.   if (!(pf != 2 || pr != 6 || bf != 1 || br != 8))
  413.   { if (wf <= 3 && wr == 6) return(0);
  414.     if (wf == 4 && wr == 8) return(0);
  415.   }
  416.   if (pr == 7)
  417.   { if (wr < 8 && wpp == 2 && bq == 0) return(1);
  418.     if (wr == 6 && wf == pf && bq == 0) return(1);
  419.     if (wr >= 6 && wpp <= 2 && bq != 0) return(1);
  420.   }
  421.   blpuu = dist_ (bf, br, pf - 1, pr + 2);
  422.   wbdd = dist_ (wf, wr, bf, br - 2);
  423.   brpuu = dist_ (bf, br, pf + 1, pr + 2);
  424.   if (pr == 6)
  425.   { if (dist_ (bf, br, pf + 1, pr) > 1 &&
  426.         brpuu > dist_ (wf, wr, pf + 1, pr)) return(1);
  427.     if (pf != 1)
  428.     { if (blpuu > dist_ (wf, wr, pf - 1, pr)) return(1);
  429.       if (br == 8 && mbpf == 1 && wbdd == 1) return(1);
  430.       if (br > 6 && nbpf == 2 && dist_ (wf, wr, bf, 5) <= 1) return(1);
  431.     }
  432.     else
  433.       if (wf == 1 && wr == 8 && bf == 2 && br == 6) return(0);
  434.   }
  435.   mwpf = wf - pf;
  436.   if (mwpf < 0) mwpf = -mwpf;
  437.   if (pr >= 5 && mwpf == 2 && wr == pr && bf == wf && br - pr == 2) return(1);
  438.   brpu = dist_ (bf, br, pf + 1, pr + 1);
  439.   wrpu = dist_ (wf, wr, pf + 1, pr + 1);
  440.   blpu = dist_ (bf, br, pf - 1, pr + 1);
  441.   wlpu = dist_ (wf, wr, pf - 1, pr + 1);
  442.   if (!(pf == 1 || pr != 5))
  443.   { if (mwpf <= 1 && wr - pr == 1) return(1);
  444.     if (wrpu == 1 && brpu > 1) return(1);
  445.     if (wr >= 4 && bf == wf && br - pr >= 2 && mbpf == 3) return(1);
  446.     if (wlpu == 1 && blpu > 1) return(1);
  447.   }
  448.   if (pr == 2 && br == 3 && mbpf > 1 && dist_ (wf, wr, bf, br + 2) <= 1) return(1);
  449.   if (wr - pr == 2 && br == pr && mbpf == 1 && mwpf > 1 &&
  450.       (wf - pf) * (bf - pf) > 0) return(0);
  451.   if (pf == 1 && wf == 1 && wr == br && bf > 3) return(1);
  452.   sgf = pf - 1;
  453.   if (wf >= pf) { sgf = pf + 1; }
  454.   sgr = wr - (mwpf - 1);
  455.   if (mwpf == 0 && wr > br) sgr = wr - 1;
  456.   wsg = dist_ (wf, wr, sgf, sgr);
  457.   if (wr - pr - mwpf > 0 && wr - br >= -1 && bpp - (wsg + (sgr - ppr))
  458.       >= -1 && dist_ (bf, br, sgf, sgr) > wsg) return(1);
  459.   md = mbpf - mwpf;
  460.   if (!(pf != 1 || bf <= 3))
  461.   { sdr = br + (bf - 3);
  462.     if (sdr > 8) sdr = 8;
  463.     if (wr > br + 1) sdr = br;
  464.     if (sdr > ppr)
  465.     { wsd = dist_ (wf, wr, 3, sdr);
  466.       bsd = dist_ (bf, br, 3, sdr);
  467.       if (bsd - wsd < -1) return(0);
  468.       if (bsd <= wsd && md <= 0) return(0);
  469.     }
  470.   }
  471.   brpuuu = dist_ (bf, br, pf + 1, pr + 3);
  472.   if (brpu > wrpu && brpuuu > wrpu && pr - wr != pf - wf) return(1);
  473.   if (brpuuu == 0 && wrpu == 1) return(1);
  474.   blpuuu = dist_ (bf, br, pf - 1, pr + 3);
  475.   if (pf != 1)
  476.   { if (blpu > wlpu && blpuuu > wlpu && pr - wr != wf - pf) return(1);
  477.     if (blpuuu == 0 && wlpu == 1) return(1);
  478.   }
  479.   wrpuu = dist_ (wf, wr, pf + 1, pr + 2);
  480.   if (brpuu > wrpuu) return(1);
  481.   wlpuu = dist_ (wf, wr, pf - 1, pr + 2);
  482.   if (pf > 1 && blpuu > wlpuu) return(1);
  483.   if (br == pr)
  484.   { if (mwpf <= 2 && wr - pr == -1 && mbpf != 2) return(1);
  485.     if (dist_ (wf, wr, bf - 1, br + 2) <= 1 && bf - pf > 1) return(1);
  486.     if (dist_ (wf, wr, bf + 1, br + 2) <= 1 && bf - pf < -1) return(1);
  487.   }
  488.   if (pf != 1)
  489.   { if (br == pr && mbpf > 1 && dist_ (wf, wr, pf, pr - 1) <= 1) return(1);
  490.     if (br - pr >= 3 && wbdd == 1) return(1);
  491.     if (wr - pr >= 2 && wr < br && md >= 0) return(1);
  492.     if (mwpf <= 2 && wr - pr >= 3 && bf != pf && wr - br <= 1) return(1);
  493.     if (wr >= pr && br - pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) return(1);
  494.     if (md >= -1 && pr == 2 && br == 8) return(1);
  495.   }
  496.   tbf = bf - 1;
  497.   if (pf > bf) tbf = bf + 1;
  498.   if (mbpf > 1 && br == ppr && dist_ (wf, wr, tbf, wr + 2) <= 1) return(1);
  499.   if (br == pr && bf - pf == -2 && dist_ (wf, wr, pf + 2, pr - 1) <= 1) return(1);
  500.   if (pf > 2 && br == pr && bf - pf == 2 &&
  501.       dist_ (wf, wr, pf - 2, pr - 1) <= 1) return(1);
  502.   return(0);
  503. }                /* kpkwv_ */
  504.  
  505. short 
  506. kpkbv_ (short pf, short pr, short wf, short wr, short bf, short br)
  507. {
  508.   static short incf[8] =
  509.     {0, 1, 1, 1, 0, -1, -1, -1};
  510.   static short incr[8] =
  511.     {1, 1, 0, -1, -1, -1, 0, 1};
  512.  
  513.   short dist_ (short, short, short, short);
  514.   short kpkwv_ (short, short, short, short, short, short);
  515.   static short i, nm, nbf, nbr;
  516.  
  517.   nm = 0;
  518.   for (i = 0; i < 8; ++i)
  519.     {
  520.       nbf = bf + incf[i];
  521.       if (nbf < 1 || nbf > 8) continue;
  522.       nbr = br + incr[i];
  523.       if (nbr < 1 || nbr > 8) continue;
  524.       if (dist_ (nbf, nbr, wf, wr) < 2) continue;
  525.       if (nbf == pf && nbr == pr) return(0);
  526.       if (nbr == pr + 1 && (nbf == pf - 1 || nbf == pf + 1)) continue;
  527.       ++nm;
  528.       if (kpkwv_ (pf, pr, wf, wr, nbf, nbr) == 0) return(0);
  529.     }
  530.   if (nm > 0) return(-1);
  531.   return(0);
  532. }                /* kpkbv_ */
  533.  
  534. short 
  535. dist_ (short f1, short r1, short f2, short r2)
  536. {
  537.   short ts;
  538.   static short fd, rd;
  539.  
  540.   fd = f2 - f1;
  541.   if (fd < 0) fd = -fd;
  542.  
  543.   rd = r2 - r1;
  544.   if (rd < 0) rd = -rd;
  545.  
  546.  ts = ((rd > fd) ? rd : fd);
  547.  return(ts);
  548. }                /* dist_ */
  549.  
  550. inline
  551. int
  552. ScoreK1PK (short side,
  553.        short winner,
  554.        short loser,
  555.        short king1,
  556.        register short king2,
  557.        register short sq)
  558.  
  559.      /*
  560.       *  We call Don Beal's routine with the necessary parameters and determine
  561.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  562.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  563.       *  a decisive winning/drawing line.
  564.       */
  565.  
  566. {
  567. #ifdef WAY4PL64
  568.   short s;
  569. #endif
  570.   short win, sqc, sqr, k1c, k1r, k2c, k2r;
  571.   const int drawn = 10, won = 500;
  572.  
  573. #ifdef WAY4PL64
  574. #ifdef CACHE
  575.   if (ProbeEETable(side,&s)) return s;
  576. #endif
  577. #endif
  578.   sqc = column (sq) + 1;
  579.   sqr = row (sq) + 1;
  580.   k1c = column (king1) + 1;
  581.   k1r = row (king1) + 1;
  582.   k2c = column (king2) + 1;
  583.   k2r = row (king2) + 1;
  584.   if (winner == black)
  585.     {
  586.       sqr = 9 - sqr;
  587.       k1r = 9 - k1r;
  588.       k2r = 9 - k2r;
  589.     }
  590.   if (sqc > 4)
  591.     {
  592.       sqc = 9 - sqc;
  593.       k1c = 9 - k1c;
  594.       k2c = 9 - k2c;
  595.     }
  596.  
  597.   if (side == winner)
  598.     win = kpkwv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  599.   else
  600.     win = kpkbv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  601.  
  602. #ifdef WAY4PL64
  603.   if (!win)  s = drawn + 5 * distance (sq, king2) - 5*distance(king1,king2);
  604.   else       s = won + 50 * (sqr - 2) + 10*distance(sq,king2);
  605. #else
  606.   if (!win)
  607.     return drawn + 5 * distance (sq, king2);
  608.   else
  609.     return won + 50 * (sqr - 2);
  610. #endif
  611.  
  612. #ifdef WAY4PL64
  613. #ifdef CACHE 
  614.   if (PUTVAR) PutInEETable (side, s); 
  615. #endif 
  616.  
  617.   return s;
  618. #endif
  619. }
  620.  
  621. inline
  622. short
  623. ScoreLoneKing (short side)
  624.  
  625.      /*
  626.       * Static evaluation when loser has only a king and winner has no pawns or no
  627.       * pieces.
  628.       */
  629.  
  630. {
  631. //  short ts;
  632.   register short winner, loser, king1, king2, s, i;
  633.  
  634.   if (mtl[white] == valueK && mtl[black] == valueK)
  635.     return 0;
  636.   UpdateWeights ();
  637.   winner = ((mtl[white] > mtl[black]) ? white : black);
  638.   loser = winner ^ 1;
  639.   king1 = PieceList[winner][0];
  640.   king2 = PieceList[loser][0];
  641.  
  642.   s = 0;
  643.  
  644.   if (pmtl[winner] == 0)
  645.     {
  646.       if (emtl[winner] == valueB + valueN)
  647.     s = ScoreKBNK (winner, king1, king2);
  648.       else if (emtl[winner] == valueN + valueN)
  649.     s = 0;
  650.     else if (emtl[winner] < valueR)
  651.        s = 0;
  652.       else
  653.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  654.     }
  655.   else
  656.     {
  657.       if (pmtl[winner] == valueP)
  658.     s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  659.       else
  660.     for (i = 1; i <= PieceCnt[winner]; i++)
  661.       s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  662.     }
  663.   if (side != winner)
  664.     s = 0 - s;
  665.   return(s);
  666. //  ts = ((side == winner) ? s : -s);
  667. //  return (ts);
  668. }
  669.  
  670. #else // old pre 4pl67 code
  671.  
  672. short dist_ (short f1, short r1, short f2, short r2)
  673. {
  674.   return distdata [ f1-9+8*r1 ][ f2-9+8*r2 ];
  675. }
  676.  
  677. short 
  678. kpkwv_ (short pf, short pr, short wf, short wr, short bf, short br)
  679. {
  680.  
  681.   /*
  682.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  683.    */
  684.  
  685.  
  686.   const short drawn=0, win=1;
  687.   
  688.   short wbdd, mbpf, blpu;
  689.   short brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  690.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  691.  
  692.  
  693.   ppr = pr;
  694.   if (pr == 2) { ppr = 3; }
  695.   if (pf != 1) { goto L2; }
  696.   if (bf != 3) { goto L1; }
  697.   if (pr == 7 && wf == 1 && wr == 8 && br > 6) return drawn;
  698.   if (pr == 6 && wf < 4 && wr == 6 && br == 8) return win;
  699. L1:
  700.   if (bf == 1 && br > pr) return drawn;
  701.   if (pr == 7 && bf > 2) return win;
  702.   if (bf <= 3 && br - ppr > 1) return drawn;
  703.   if (wf == 1 && bf == 3 && wr - pr == 1 && br - pr == 1) return drawn;
  704. L2:
  705.   bq = dist_ (bf, br, pf, 8);
  706.   if (bq > 8 - ppr) return win;
  707.   mbpf = bf - pf;
  708.   if (mbpf < 0) { mbpf = -mbpf; }
  709.   bpp = dist_ (bf, br, pf, ppr);
  710.   wpp = dist_ (wf, wr, pf, ppr);
  711.   if (bpp - wpp < -1 && br - pr != mbpf) return drawn;
  712.   if (pf == 1 && pr <= 3 && wf <= 2 && wr == 8 && bf == 4 && br >= 7) return win;
  713.   if (pf != 2 || pr != 6 || bf != 1 || br != 8) { goto L3; }
  714.   if (wf <= 3 && wr == 6) return drawn;
  715.   if (wf == 4 && wr == 8) return drawn;
  716. L3:
  717.   if (pr != 7) { goto L4; }
  718.   if (wr < 8 && wpp == 2 && bq == 0) return win;
  719.   if (wr == 6 && wf == pf && bq == 0) return win;
  720.   if (wr >= 6 && wpp <= 2 && bq != 0) return win;
  721. L4:
  722.   blpuu = dist_ (bf, br, pf-1, pr+2);
  723.   wbdd = dist_ (wf, wr, bf, br-2);
  724.   brpuu = dist_ (bf, br, pf+1, pr+2);
  725.   if (pr != 6) { goto L6; }
  726.   if (dist_ (bf, br, pf+1, pr) > 1 && brpuu > dist_ (wf, wr, pf+1, pr)) return win;
  727.   if (pf == 1) { goto L5; }
  728.   if (blpuu > dist_ (wf, wr, pf-1, pr)) return win;
  729.   if (br == 8 && mbpf == 1 && wbdd == 1) return win;
  730.   if (br > 6 && mbpf == 2 && dist_ (wf, wr, bf, 5) <= 1) return win;
  731.   goto L6;
  732. L5:
  733.   if (wf == 1 && wr == 8 && bf == 2 && br == 6) return drawn;
  734. L6:
  735.   mwpf = wf - pf;
  736.   if (mwpf < 0) { mwpf = -mwpf; }
  737.   if (pr >= 5 && mwpf == 2 && wr == pr && bf == wf && br - pr == 2) return win;
  738.   brpu = dist_ (bf, br, pf+1, pr+1);
  739.   wrpu = dist_ (wf, wr, pf+1, pr+1);
  740.   blpu = dist_ (bf, br, pf-1, pr+1);
  741.   wlpu = dist_ (wf, wr, pf-1, pr+1);
  742.   if (pf == 1 || pr != 5) { goto L7; }
  743.   if (mwpf <= 1 && wr - pr == 1) return win;
  744.   if (wrpu == 1 && brpu > 1) return win;
  745.   if (wr >= 4 && bf == wf && br - pr >= 2 && mbpf == 3) return win;
  746.   if (wlpu == 1 && blpu > 1) return win;
  747. L7:
  748.   if (pr == 2 && br == 3 && mbpf > 1 && dist_ (wf, wr, bf, br+2) <= 1) return win;
  749.   if (wr - pr == 2 && br == pr && mbpf == 1 && mwpf > 1 && (wf - pf) *
  750.       (bf - pf) > 0) return drawn;
  751.   if (pf == 1 && wf == 1 && wr == br && bf > 3) return win;
  752.   sgf = pf - 1;
  753.   if (wf >= pf) { sgf = pf + 1; }
  754.   sgr = wr - (mwpf - 1);
  755.   if (mwpf == 0 && wr > br) { sgr = wr - 1; }
  756.   wsg = dist_ (wf, wr, sgf, sgr);
  757.   if (wr - pr - mwpf > 0 && wr - br >= -1 && bpp - (wsg + (sgr - ppr))
  758.       >= -1 && dist_ (bf, br, sgf, sgr) > wsg) return win;
  759.   md = mbpf - mwpf;
  760.   if (pf != 1 || bf <= 3) { goto L8; }
  761.   sdr = br + (bf - 3);
  762.   if (sdr > 8) { sdr = 8; }
  763.   if (wr > br + 1) { sdr = br; }
  764.   if (sdr <= ppr) { goto L8; }
  765.   wsd = dist_ (wf, wr, 3, sdr);
  766.   bsd = dist_ (bf, br, 3, sdr);
  767.   if (bsd - wsd < -1) return drawn;
  768.   if (bsd <= wsd && md <= 0) return drawn;
  769. L8:
  770.   brpuuu = dist_ (bf, br, pf+1, pr+3);
  771.   if (brpu > wrpu && brpuuu > wrpu && pr - wr != pf - wf) return win;
  772.   if (brpuuu == 0 && wrpu == 1) return win;
  773.   blpuuu = dist_ (bf, br, pf-1, pr+3);
  774.   if (pf == 1) { goto L9; }
  775.   if (blpu > wlpu && blpuuu > wlpu && pr - wr != wf - pf) return win;
  776.   if (blpuuu == 0 && wlpu == 1) return win;
  777. L9:
  778.   wrpuu = dist_ (wf, wr, pf+1, pr+2);
  779.   if (brpuu > wrpuu) return win;
  780.   wlpuu = dist_ (wf, wr, pf-1, pr+2);
  781.   if (pf > 1 && blpuu > wlpuu) return win;
  782.   if (br != pr) { goto L10; }
  783.   if (mwpf <= 2 && wr - pr == -1 && mbpf != 2) return win;
  784.   if (dist_ (wf, wr, bf-1, br+2) <= 1 && bf - pf > 1) return win;
  785.   if (dist_ (wf, wr, bf+1, br+2) <= 1 && bf - pf < -1) return win;
  786. L10:
  787.   if (pf == 1) { goto L11; }
  788.   if (br == pr && mbpf > 1 && dist_ (wf, wr, pf, pr-1) <= 1) return win;
  789.   if (br - pr >= 3 && wbdd == 1) return win;
  790.   if (wr - pr >= 2 && wr < br && md >= 0) return win;
  791.   if (mwpf <= 2 && wr - pr >= 3 && bf != pf && wr - br <= 1) return win;
  792.   if (wr >= pr && br - pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) return win;
  793.   if (md >= -1 && pr == 2 && br == 8) return win;
  794. L11:
  795.   tbf = bf - 1;
  796.   if (pf > bf) { tbf = bf + 1; }
  797.   if (mbpf > 1 && br == ppr && dist_ (wf, wr, tbf, wr+2) <= 1) return win;
  798.   if (br == pr && bf - pf == -2 && dist_ (wf, wr, pf+2, pr-1) <= 1) return win;
  799.   if (pf > 2 && br == pr && bf - pf == 2 && dist_ (wf, wr, pf-2, pr-1) <= 1) return win;
  800.  
  801.   return drawn;
  802. }                /* kpkwv_ */
  803.  
  804. short 
  805. kpkbv_ (short pf, short pr, short wf, short wr, short bf, short br)
  806. {
  807.   /* Initialized data */
  808.  
  809.   static short incf[8] =
  810.   {0, 1, 1, 1, 0, -1, -1, -1};
  811.   static short incr[8] =
  812.   {1, 1, 0, -1, -1, -1, 0, 1};
  813.  
  814.   /* System generated locals */
  815.   short ret_val;
  816.  
  817.   /* Local variables */
  818.   static short i;
  819.   static short nm, nbf, nbr;
  820.  
  821.   ret_val = 0;
  822.   nm = 0;
  823.   for (i = 1; i <= 8; ++i)
  824.     {
  825.       nbf = bf + incf[i - 1];
  826.       if (nbf < 1 || nbf > 8) { goto L1; }
  827.       nbr = br + incr[i - 1];
  828.       if (nbr < 1 || nbr > 8) { goto L1; }
  829.       if (dist_ (nbf, nbr, wf, wr) < 2) { goto L1; }
  830.       if (nbf == pf && nbr == pr) { goto L2; }
  831.       if (nbr == pr + 1 && (nbf == pf - 1 || nbf == pf + 1)) { goto L1; }
  832.       ++nm;
  833.       if (kpkwv_ (pf, pr, wf, wr, nbf, nbr) == 0) { goto L2; }
  834.     L1:
  835.       ;
  836.     }
  837.   if (nm > 0) { ret_val = -1; }
  838. L2:
  839.   return ret_val;
  840. }                /* kpkbv_ */
  841.  
  842.  
  843. inline
  844. int
  845. ScoreK1PK (short int side,
  846.        short int winner,
  847.        short int loser,
  848.        short int king1,
  849.        register short int king2,
  850.        register short int sq)
  851.  
  852.      /*
  853.       *  We call Don Beal's routine with the necessary parameters and determine
  854.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  855.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  856.       *  a decisive winning/drawing line.
  857.       */
  858.  
  859. {
  860.   short s, win, sqc, sqr, k1c, k1r, k2c, k2r;
  861.   const int drawn = 10, won = 500;
  862.  
  863. #ifdef CACHE
  864.   if (ProbeEETable(side,&s)) return s;
  865. #endif
  866.  
  867.   sqc = column (sq) + 1;
  868.   sqr = row (sq) + 1;
  869.   k1c = column (king1) + 1;
  870.   k1r = row (king1) + 1;
  871.   k2c = column (king2) + 1;
  872.   k2r = row (king2) + 1;
  873.   if (winner == black)
  874.     {
  875.       sqr = 9 - sqr;
  876.       k1r = 9 - k1r;
  877.       k2r = 9 - k2r;
  878.     }
  879.   if (sqc > 4)
  880.     {
  881.       sqc = 9 - sqc;
  882.       k1c = 9 - k1c;
  883.       k2c = 9 - k2c;
  884.     }
  885.  
  886.   if (side == winner) win = kpkwv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  887.   else                win = kpkbv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  888.  
  889.   if (!win)  s = drawn + 5 * distance (sq, king2) - 5*distance(king1,king2);
  890.   else       s = won + 50 * (sqr - 2) + 10*distance(sq,king2);
  891. //  if (!win)  s = drawn + 5 * distance (sq, king2); // old 2.50 way
  892. //  else       s = won + 50 * (sqr - 2); // old 2.50 way
  893.  
  894. #ifdef CACHE 
  895.   if (PUTVAR) PutInEETable (side, s); 
  896. #endif 
  897.  
  898.   return s;
  899. }
  900.  
  901.  
  902. inline
  903. short int
  904. ScoreLoneKing (ARGSZ int side)
  905.  
  906. /*
  907.  * Static evaluation when loser has only a king and winner has no pawns or no
  908.  * pieces.
  909.  */
  910.  
  911. {
  912.     register short winner, loser, king1, king2, s, i;
  913.  
  914.   if (mtl[white] == valueK && mtl[black] == valueK)
  915.     return 0;
  916.     UpdateWeights ();
  917.     winner = ((mtl[white] > mtl[black]) ? white : black);
  918.     loser = winner ^ 1;
  919.     king1 = PieceList[winner][0];
  920.     king2 = PieceList[loser][0];
  921.  
  922.     s = 0;
  923.  
  924.   if (pmtl[winner] == 0)
  925.     {
  926.     if (emtl[winner] == valueB + valueN)
  927.       s = ScoreKBNK (winner, king1, king2);
  928.       else if (emtl[winner] == valueN + valueN || 
  929.                emtl[winner] == valueN || emtl[winner] == valueB)
  930.     s = 0; 
  931.       else
  932.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  933.     }
  934.   else {
  935.     if (pmtl[winner] == valueP)
  936.         s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  937.       else for (i = 1; i <= PieceCnt[winner]; i++)
  938.         s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  939.     }
  940.  
  941.     if (side != winner)
  942.      s = 0 - s;
  943.     return(s);
  944. /*    return ((side == winner) ? s : -s);*/
  945. }
  946.  
  947. #endif // old eval pre 4pl67 way
  948.  
  949.  
  950. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  951.  
  952. /*
  953.  * Inputs are:
  954.  * pmtl[side] - value of pawns
  955.  * mtl[side]  - value of all material
  956.  * emtl[side] - vaule of all material - value of pawns - value of king
  957.  * hung[side] - count of hung pieces
  958.  * Tscore[ply] - search tree score for ply
  959.  * ply
  960.  * Pscore[ply] - positional score for ply ply
  961.  * INCscore    - bonus score or penalty for certain positions
  962.  * slk - single lone king flag
  963.  * Sdepth - search goal depth
  964.  * xwndw - evaluation window about alpha/beta
  965.  * EWNDW - second evaluation window about alpha/beta
  966.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  967.  * PC1[column] - # of my pawns in this column
  968.  * PC2[column] - # of opponents pawns in column
  969.  * PieceCnt[side] - just what it says
  970.  */
  971. inline
  972. int
  973. ScoreKPK (short side,
  974.       short winner,
  975.       short loser,
  976.       short king1,
  977.       register short king2,
  978.       register short sq)
  979.  
  980. /*
  981.  * Score King and Pawns versus King endings.
  982.  */
  983.  
  984. {
  985.     register short s, r;
  986.  
  987.     s = ((PieceCnt[winner] == 1) ? 50 : 120);
  988.     if (winner == white)
  989.       {
  990.       r = row (sq) - ((side == loser) ? 1 : 0);
  991.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  992.           s += 10 * row (sq);
  993.       else
  994.           s = 500 + 50 * row (sq);
  995.       if (row (sq) < 6)
  996.           sq += 16;
  997.       else if (row (sq) == 6)
  998.           sq += 8;
  999.       }
  1000.     else
  1001.       {
  1002.       r = row (sq) + ((side == loser) ? 1 : 0);
  1003.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  1004.           s += 10 * (7 - row (sq));
  1005.       else
  1006.           s = 500 + 50 * (7 - row (sq));
  1007.       if (row (sq) > 1)
  1008.           sq -= 16;
  1009.       else if (row (sq) == 1)
  1010.           sq -= 8;
  1011.       }
  1012.     s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  1013.     return (s);
  1014. }
  1015.  
  1016. inline
  1017. int
  1018. ScoreKBNK (short winner, short king1, short king2)
  1019.  
  1020.  
  1021. /*
  1022.  * Score King+Bishop+Knight versus King endings.  Works fine now.
  1023.  */
  1024.  
  1025. {
  1026.     register short s, Bsq, Nsq, KBNKsq = 0;
  1027.  
  1028.     if (board[PieceList[winner][1]] == bishop)
  1029.       {
  1030.         Bsq = PieceList[winner][1];
  1031.         Nsq = PieceList[winner][2];
  1032.       }
  1033.     else
  1034.       {
  1035.         Bsq = PieceList[winner][2];
  1036.         Nsq = PieceList[winner][1];
  1037.       }
  1038.  
  1039.     KBNKsq = (((row (Bsq) % 2) == (column (Bsq) % 2)) ? 0 : 7);
  1040.  
  1041.     s = emtl[winner] - 300;
  1042.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  1043.  
  1044. //  The following 2 lines are a fix for this version
  1045.    s -= (8*taxicab(king1,king2) + 2*distance(Nsq,king2) + 
  1046.                                     distance(Bsq,king2)); 
  1047.    s += KingEnding[king1];
  1048.     return (s);
  1049. }
  1050.  
  1051. int
  1052. evaluate (register short side,
  1053.       register short ply,
  1054.       register short depth,
  1055.           register short ext,
  1056.       register short alpha,
  1057.       register short beta,
  1058.       short INCscore,
  1059.       short *InChk)    /* output Check flag */
  1060.  
  1061. /*
  1062.  * Compute an estimate of the score by adding the positional score from the
  1063.  * previous ply to the material difference. If this score falls inside a
  1064.  * window which is 180 points wider than the alpha-beta window (or within a
  1065.  * 50 point window during quiescence search) call ScorePosition() to
  1066.  * determine a score, otherwise return the estimated score. If one side has
  1067.  * only a king and the other either has no pawns or no pieces then the
  1068.  * function ScoreLoneKing() is called.
  1069.  */
  1070.  
  1071. {
  1072.     register short xside;
  1073.     register short slk;
  1074.     short s;
  1075.  
  1076.     xside = side ^ 1;
  1077.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  1078.     hung[white] = hung[black] = 0;
  1079.     slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  1080.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  1081.  
  1082.           /* should we use the estimete or score the position */
  1083.     if ( !slk && (ply == 1 ||
  1084. #ifdef CACHE
  1085.         (CheckEETable (side)) ||
  1086. #endif
  1087.         (myneweval ? ((
  1088.         (ply==Sdepth || (!ext && depth == 0 && s>=alpha-30 && s<=beta+30)) ||
  1089.         (ext && (s >= (alpha - 30) && s <= (beta + 30)) )) )
  1090.         :
  1091.         ((Sdepth ==  ply) ||
  1092.         (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30)) )) )
  1093.         ))
  1094.  
  1095.       {
  1096.       /* score the position */
  1097.       ataks (side, atak[side]);
  1098.       if (Anyatak (side, PieceList[xside][0])){
  1099.       ataks (xside, atak[xside]);
  1100.       ChkFlag[ply-1] = *InChk = Anyatak (xside, PieceList[side][0]);
  1101.           return (10001 - ply);
  1102.       }
  1103.       ataks (xside, atak[xside]);
  1104.       ChkFlag[ply-1] = *InChk = Anyatak (xside, PieceList[side][0]);
  1105.  
  1106. #ifndef BAREBONES 
  1107.       EvalNodes++;
  1108. #endif
  1109.     if(ply>4)PUTVAR=true;
  1110.           s = ScorePosition (side);
  1111.     PUTVAR=false;
  1112.       }
  1113.     else
  1114.       {
  1115.       /* use the estimate but look at check and slk */
  1116.        *InChk = SqAtakd (PieceList[side][0], xside);
  1117.        ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  1118.        if (SqAtakd (PieceList[xside][0], side)){ return (10001 - ply); }
  1119. #ifdef DEBUG 
  1120.        if(debuglevel & 4096){
  1121.       printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  1122.       }
  1123. #endif
  1124.       if (slk){
  1125.         if(ply>4)PUTVAR=true;
  1126.               s = ScoreLoneKing (side);
  1127.         PUTVAR=false;}
  1128.       }
  1129.  
  1130.     Pscore[ply] = s - mtl[side] + mtl[xside];
  1131.     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  1132.     QueenCheck[ply - 1] =       /* tom@izf.tno.nl */
  1133.           ((*InChk) && board[TOsquare] == queen) ? TOsquare : 0;
  1134. #ifdef DEBUG 
  1135.        if(debuglevel & 4096){
  1136.     printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  1137.     }
  1138. #endif
  1139.     return (s);
  1140. }
  1141.  
  1142. inline
  1143. int
  1144. BRscan (register short sq, short *mob)
  1145.  
  1146. /*
  1147.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  1148.  * hung[] array if a pin is found.
  1149.  */
  1150. {
  1151.     register unsigned char *ppos, *pdir;
  1152.     register short s, mobx;
  1153.     register short u, pin;
  1154.     short piece, *Kf;
  1155.     mobx = s = 0;
  1156.     Kf = Kfield[c1];
  1157.     piece = board[sq];
  1158.     ppos = nextpos[piece][sq];
  1159.     pdir = nextdir[piece][sq];
  1160.     u = ppos[sq];
  1161.     pin = -1;            /* start new direction */
  1162.     do
  1163.       {
  1164.       s += Kf[u];
  1165.       if (color[u] == neutral)
  1166.         {
  1167.         mobx++;
  1168.         if (ppos[u] == pdir[u])
  1169.             pin = -1;    /* oops new direction */
  1170.         u = ppos[u];
  1171.         }
  1172.       else if (pin < 0)
  1173.         {
  1174.         if (board[u] == pawn || board[u] == king)
  1175.             u = pdir[u];
  1176.         else
  1177.           {
  1178.               if (ppos[u] != pdir[u])
  1179.               pin = u;    /* not on the edge and on to find a pin */
  1180.               u = ppos[u];
  1181.           }
  1182.         }
  1183.       else
  1184.         {
  1185.         if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  1186.           {
  1187.               if (color[pin] == c2)
  1188.             {
  1189.                 s += PINVAL;
  1190.                 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  1191.                 ++hung[c2];
  1192.             }
  1193.               else
  1194.               s += XRAY;
  1195.           }
  1196.         pin = -1;    /* new direction */
  1197.         u = pdir[u];
  1198.         }
  1199.       }
  1200.     while (u != sq);
  1201.     *mob = mobx;
  1202.     return s;
  1203. }
  1204.  
  1205. inline
  1206. short
  1207. KingScan (register short sq)
  1208.  
  1209. /*
  1210.  * Assign penalties if king can be threatened by checks, if squares near the
  1211.  * king are controlled by the enemy (especially the queen), or if there are
  1212.  * no pawns near the king. 
  1213.     The following must be true: 
  1214.         board[sq] == king 
  1215.         c1 == color[sq] 
  1216.         c2 == otherside[c1]
  1217.  */
  1218.  
  1219. #define ScoreThreat \
  1220.     if (color[u] != c2)\
  1221.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  1222.       else s -= 3
  1223.  
  1224. {
  1225.     register short cnt;
  1226.     register unsigned char *ppos, *pdir;
  1227.     register short s;
  1228.     register short u;
  1229.     short ok;
  1230.  
  1231.     s = 0;
  1232.     cnt = 0;
  1233.     if (HasBishop[c2] || HasQueen[c2])
  1234.       {
  1235.       ppos = nextpos[bishop][sq];
  1236.       pdir = nextdir[bishop][sq];
  1237.       u = ppos[sq];
  1238.       do
  1239.         {
  1240.         if (atk2[u] & ctlBQ)
  1241.             ScoreThreat;
  1242.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1243.         }
  1244.       while (u != sq);
  1245.       }
  1246.     if (HasRook[c2] || HasQueen[c2])
  1247.       {
  1248.       ppos = nextpos[rook][sq];
  1249.       pdir = nextdir[rook][sq];
  1250.       u = ppos[sq];
  1251.       do
  1252.         {
  1253.         if (atk2[u] & ctlRQ)
  1254.             ScoreThreat;
  1255.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1256.         }
  1257.       while (u != sq);
  1258.       }
  1259.     if (HasKnight[c2])
  1260.       {
  1261.       pdir = nextdir[knight][sq];
  1262.       u = pdir[sq];
  1263.       do
  1264.         {
  1265.         if (atk2[u] & ctlNN)
  1266.             ScoreThreat;
  1267.         u = pdir[u];
  1268.         }
  1269.       while (u != sq);
  1270.       }
  1271.     s += (KSFTY * KTHRT[cnt]) / 16;
  1272.  
  1273.     cnt = 0;
  1274.     ok = false;
  1275.     pdir = nextpos[king][sq];
  1276.     u = pdir[sq];
  1277.     do
  1278.       {
  1279.       if (board[u] == pawn)
  1280.           ok = true;
  1281.       if (atk2[u] > atk1[u])
  1282.         {
  1283.         ++cnt;
  1284.         if (atk2[u] & ctlQ)
  1285.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  1286.             s -= 4 * KSFTY;
  1287.         }
  1288.       u = pdir[u];
  1289.       }
  1290.     while (u != sq);
  1291.     if (!ok)
  1292.     s -= KSFTY;
  1293.     if (cnt > 1)
  1294.     s -= (KSFTY);
  1295.     return (s);
  1296. }
  1297.  
  1298. inline
  1299. int
  1300. trapped (register short sq)
  1301.  
  1302. /*
  1303.  * See if the attacked piece has unattacked squares to move to. The following
  1304.  * must be true: c1 == color[sq] c2 == otherside[c1]
  1305.  */
  1306.  
  1307. {
  1308.     register short u;
  1309.     register unsigned char *ppos, *pdir;
  1310.     register short piece;
  1311.  
  1312.     piece = board[sq];
  1313.     ppos = nextpos[ptype[c1][piece]][sq];
  1314.     pdir = nextdir[ptype[c1][piece]][sq];
  1315.     if (piece == pawn)
  1316.       {
  1317.       u = ppos[sq];        /* follow no captures thread */
  1318.       if (color[u] == neutral)
  1319.         {
  1320.         if (atk1[u] >= atk2[u])
  1321.             return (false);
  1322.         if (atk2[u] < ctlP)
  1323.           {
  1324.               u = ppos[u];
  1325.               if (color[u] == neutral && atk1[u] >= atk2[u])
  1326.               return (false);
  1327.           }
  1328.         }
  1329.       u = pdir[sq];        /* follow captures thread */
  1330.       if (color[u] == c2)
  1331.           return (false);
  1332.       u = pdir[u];
  1333.       if (color[u] == c2)
  1334.           return (false);
  1335.       }
  1336.     else
  1337.       {
  1338.       u = ppos[sq];
  1339.       do
  1340.         {
  1341.         if (color[u] != c1)
  1342.             if (atk2[u] == 0 || board[u] >= piece)
  1343.             return (false);
  1344.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1345.         }
  1346.       while (u != sq);
  1347.       }
  1348.     return (true);
  1349. }
  1350.  
  1351.  
  1352.  
  1353. #define PAWNVALUE_4PL69 1
  1354. #ifdef PAWNVALUE_4PL69
  1355. // this is PawnValue from 4PL69
  1356. static inline int
  1357. PawnValue (register short sq, short side)
  1358. /*
  1359.  * Calculate the positional value for a pawn on 'sq'.
  1360.  */
  1361. {
  1362.     register short fyle, rank;
  1363.     register short j, s, a1, a2, in_square, r, e;
  1364.  
  1365.     a1 = (atk1[sq] & 0x4FFF);
  1366.     a2 = (atk2[sq] & 0x4FFF);
  1367.     rank = row (sq);
  1368.     fyle = column (sq);
  1369.     s = 0;
  1370.     if (c1 == white)
  1371.       {
  1372.       s = Mwpawn[sq];
  1373.       if ((sq == 11 && color[19] != neutral) || (sq == 12 && color[20] != neutral)) s += PEDRNK2B;
  1374.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1375.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1376.  
  1377.       if ((atk2[sq+8] & ctlP) && !(a1 & ctlP) && !(atk1[sq+8] & ctlP))
  1378.         {
  1379.         s += BACKWARD[a2 & 0xFF];
  1380.         if (PC2[fyle] == 0) s += PWEAKH;
  1381.         if (color[sq + 8] != neutral) s += PBLOK;
  1382.         }
  1383.       if(rank != 7 && color[sq+8] == black && board[sq+8] == pawn) s -= PCRASH;
  1384.       if (PC2[fyle] == 0)
  1385.         {
  1386.         r = rank - ((side == black)?1:0);
  1387.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  1388.         e = (a2 == 0 || side == white)? 0:1;
  1389.         for (j = sq + 8; j < 64; j += 8)
  1390.             if (atk2[j] >= ctlP) { e = 2; break; }
  1391.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1392.  
  1393.         if (e == 2) s += (stage * PassedPawn3[rank]) / 10;
  1394.         else if (in_square || e == 1) s += (stage * PassedPawn2[rank]) / 10;
  1395.         else if (emtl[black] > 0) s += (stage * PassedPawn1[rank]) / 10;
  1396.         else s += PassedPawn0[rank];
  1397.         }
  1398.       }
  1399.     else if (c1 == black)
  1400.       {
  1401.       s = Mbpawn[sq];
  1402.       if ((sq == 51 && color[43] != neutral) || (sq == 52 && color[44] != neutral)) s += PEDRNK2B;
  1403.  
  1404.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1405.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1406.  
  1407.       if ((atk2[sq-8] & ctlP) && !(a1 & ctlP) && !(atk1[sq-8] & ctlP))
  1408.         {
  1409.         s += BACKWARD[a2 & 0xFF];
  1410.         if (PC2[fyle] == 0) s += PWEAKH;
  1411.         if (color[sq - 8] != neutral) s += PBLOK;
  1412.         }
  1413.       if(rank != 0 && color[sq-8] == white && board[sq-8] == pawn) s -= PCRASH;
  1414.       if (PC2[fyle] == 0)
  1415.         {
  1416.         r = rank + ((side == white)?1:0);
  1417.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  1418.         e = (a2 == 0 || side == black)?0:1;
  1419.         for (j = sq - 8; j >= 0; j -= 8)
  1420.             if (atk2[j] >= ctlP) { e = 2; break; }
  1421.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1422.  
  1423.         if (e == 2) s += (stage * PassedPawn3[7 - rank]) / 10;
  1424.         else if (in_square || e == 1) s += (stage * PassedPawn2[7 - rank]) / 10;
  1425.         else if (emtl[white] > 0) s += (stage * PassedPawn1[7 - rank]) / 10;
  1426.         else s += PassedPawn0[7 - rank];
  1427.         }
  1428.       }
  1429.     if((rank >2 && rank < 6) && (fyle > 2 && fyle < 5)) s += PCENTER;
  1430.     if (a2 > 0)
  1431.       {
  1432.       if (a1 == 0 || a2 > ctlP + 1)
  1433.         {
  1434.         s += HUNGP;
  1435.         if (trapped (sq)) hung[c1] += 2;
  1436.         hung[c1]++;
  1437.         }
  1438.       else if (a2 > a1) s += ATAKD;
  1439.       }
  1440.     return (s);
  1441. }
  1442. #else // this is Pawn value from 4PL68
  1443. // from 4pl68
  1444. static inline int
  1445. PawnValue (register short sq, short side)
  1446. /*
  1447.  * Calculate the positional value for a pawn on 'sq'.
  1448.  */
  1449.  
  1450. {
  1451.     register short fyle, rank;
  1452.     register short j, s, a1, a2, in_square, r, e;
  1453.  
  1454.     a1 = (atk1[sq] & 0x4FFF);
  1455.     a2 = (atk2[sq] & 0x4FFF);
  1456.     rank = row (sq);
  1457.     fyle = column (sq);
  1458.     s = 0;
  1459.     if (c1 == white)
  1460.       {
  1461.       s = Mwpawn[sq];
  1462.       if ((sq == 11 && color[19] != neutral) || (sq == 12 && color[20] != neutral)) s += PEDRNK2B;
  1463.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1464.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1465.  
  1466.       if (a1 < ctlP && atk1[sq + 8] < ctlP)
  1467.         {
  1468.         s += BACKWARD[a2 & 0xFF];
  1469.         if (PC2[fyle] == 0) s += PWEAKH;
  1470.         if (color[sq + 8] != neutral) s += PBLOK;
  1471.         }
  1472.       if(rank != 7 && color[sq+8] == black && board[sq+8] == pawn) s -= PCRASH;
  1473.       if (PC2[fyle] == 0)
  1474.         {
  1475.         r = rank - (side == black)?1:0;
  1476.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  1477.         e = (a2 == 0 || side == white)? 0:1;
  1478.         for (j = sq + 8; j < 64; j += 8)
  1479.             if (atk2[j] >= ctlP) { e = 2; break; }
  1480.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1481.  
  1482.         if (e == 2) s += (stage * PassedPawn3[rank]) / 10;
  1483.         else if (in_square || e == 1) s += (stage * PassedPawn2[rank]) / 10;
  1484.         else if (emtl[black] > 0) s += (stage * PassedPawn1[rank]) / 10;
  1485.         else s += PassedPawn0[rank];
  1486.         }
  1487.       }
  1488.     else if (c1 == black)
  1489.       {
  1490.       s = Mbpawn[sq];
  1491.       if ((sq == 51 && color[43] != neutral) || (sq == 52 && color[44] != neutral)) s += PEDRNK2B;
  1492.  
  1493.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1494.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1495.  
  1496.       if (a1 < ctlP && atk1[sq - 8] < ctlP)
  1497.         {
  1498.         s += BACKWARD[a2 & 0xFF];
  1499.         if (PC2[fyle] == 0) s += PWEAKH;
  1500.         if (color[sq - 8] != neutral) s += PBLOK;
  1501.         }
  1502.       if(rank != 0 && color[sq+8] == white && board[sq+8] == pawn) s -= PCRASH;
  1503.       if (PC2[fyle] == 0)
  1504.         {
  1505.         r = rank + (side == white)?1:0;
  1506.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  1507.         e = (a2 == 0 || side == black)?0:1;
  1508.         for (j = sq - 8; j >= 0; j -= 8)
  1509.             if (atk2[j] >= ctlP) { e = 2; break; }
  1510.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1511.  
  1512.         if (e == 2) s += (stage * PassedPawn3[7 - rank]) / 10;
  1513.         else if (in_square || e == 1) s += (stage * PassedPawn2[7 - rank]) / 10;
  1514.         else if (emtl[white] > 0) s += (stage * PassedPawn1[7 - rank]) / 10;
  1515.         else s += PassedPawn0[7 - rank];
  1516.         }
  1517.       }
  1518.     if((rank >2 && rank < 6) && (fyle > 2 && fyle < 5)) s += PCENTER;
  1519.     if (a2 > 0)
  1520.       {
  1521.       if (a1 == 0 || a2 > ctlP + 1)
  1522.         {
  1523.         s += HUNGP;
  1524.         if (trapped (sq)) hung[c1] += 2;
  1525.         hung[c1]++;
  1526.         }
  1527.       else if (a2 > a1) s += ATAKD;
  1528.       }
  1529.     return (s);
  1530. }
  1531. #endif // panwvalue from 4pl69 or 4pl68
  1532.  
  1533.  
  1534. inline
  1535. int
  1536. KnightValue (register short sq, short side)
  1537.  
  1538. /*
  1539.  * Calculate the positional value for a knight on 'sq'.
  1540.  */
  1541.  
  1542. {
  1543.     register short s, a2, a1;
  1544.  
  1545.     s = Mknight[c1][sq];
  1546.     a2 = (atk2[sq] & 0x4FFF);
  1547.     if (a2 > 0)
  1548.       {
  1549.       a1 = (atk1[sq] & 0x4FFF);
  1550.       if (a1 == 0 || a2 > ctlBN + 1)
  1551.         {
  1552.         s += HUNGP;
  1553.         if (trapped (sq))
  1554.             hung[c1] += 2;
  1555.         hung[c1]++;
  1556.         }
  1557.       else if (a2 >= ctlBN || a1 < ctlP)
  1558.           s += ATAKD;
  1559.       }
  1560.     return (s);
  1561. }
  1562.  
  1563. inline
  1564. int
  1565. BishopValue (register short sq, short side)
  1566.  
  1567. /*
  1568.  * Calculate the positional value for a bishop on 'sq'.
  1569.  */
  1570.  
  1571. {
  1572.     register short s;
  1573.     register short a2, a1;
  1574.     short mob;
  1575.  
  1576.     s = Mbishop[c1][sq];
  1577.     s += BRscan (sq, &mob);
  1578.     s += BMBLTY[mob];
  1579.     a2 = (atk2[sq] & 0x4FFF);
  1580.     if (a2 > 0)
  1581.       {
  1582.       a1 = (atk1[sq] & 0x4FFF);
  1583.       if (a1 == 0 || a2 > ctlBN + 1)
  1584.         {
  1585.         s += HUNGP;
  1586.         if (trapped (sq))
  1587.             hung[c1] += 2;
  1588.         hung[c1]++;
  1589.         }
  1590.       else if (a2 >= ctlBN || a1 < ctlP)
  1591.           s += ATAKD;
  1592.       }
  1593.     return (s);
  1594. }
  1595.  
  1596. inline
  1597. int
  1598. RookValue (register short sq, short side)
  1599.  
  1600. /*
  1601.  * Calculate the positional value for a rook on 'sq'.
  1602.  */
  1603.  
  1604. {
  1605.     register short s;
  1606.     register short fyle, a2, a1;
  1607.     short mob;
  1608.  
  1609.     s = RookBonus;
  1610.     s += BRscan (sq, &mob);
  1611.     s += RMBLTY[mob];
  1612.     fyle = column (sq);
  1613.     if (PC1[fyle] == 0)
  1614.     { s += RHOPN;
  1615.             if (PC2[fyle] == 0)
  1616.             s += RHOPNX;
  1617.         }
  1618.     if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  1619.     s += 10;
  1620.     if (stage > 2)
  1621.     s += 14 - taxicab (sq, EnemyKing);
  1622.     a2 = (atk2[sq] & 0x4FFF);
  1623.     if (a2 > 0)
  1624.       {
  1625.       a1 = (atk1[sq] & 0x4FFF);
  1626.       if (a1 == 0 || a2 > ctlR + 1)
  1627.         {
  1628.         s += HUNGP;
  1629.         if (trapped (sq))
  1630.             hung[c1] += 2;
  1631.         hung[c1]++;
  1632.         }
  1633.       else if (a2 >= ctlR || a1 < ctlP)
  1634.           s += ATAKD;
  1635.       }
  1636.     return (s);
  1637. }
  1638.  
  1639. inline
  1640. int
  1641. QueenValue (register short sq, short side)
  1642.  
  1643. /*
  1644.  * Calculate the positional value for a queen on 'sq'.
  1645.  */
  1646.  
  1647. {
  1648.     register short s, a2, a1;
  1649.  
  1650.     s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  1651.     if (stage > 2)
  1652.     s += 14 - taxicab (sq, EnemyKing);
  1653.     a2 = (atk2[sq] & 0x4FFF);
  1654.     if (a2 > 0)
  1655.       {
  1656.       a1 = (atk1[sq] & 0x4FFF);
  1657.       if (a1 == 0 || a2 > ctlQ + 1)
  1658.         {
  1659.         s += HUNGP;
  1660.         if (trapped (sq))
  1661.             hung[c1] += 2;
  1662.         hung[c1]++;
  1663.         }
  1664.       else if (a2 >= ctlQ || a1 < ctlP)
  1665.           s += ATAKD;
  1666.       }
  1667.     return (s);
  1668. }
  1669.  
  1670. inline
  1671. int
  1672. KingValue (register short sq, short side)
  1673.  
  1674. /*
  1675.  * Calculate the positional value for a king on 'sq'.
  1676.  */
  1677. {
  1678.     register short s;
  1679.     register short fyle;
  1680.     short a2, a1;
  1681.     s = (emtl[side ^ 1] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  1682.     if (KSFTY > 0)
  1683.     if (Developed[c2] || stage > 0)
  1684.         s += KingScan (sq);
  1685.     if (castld[c1])
  1686.     s += KCASTLD;
  1687.     else if (Mvboard[kingP[c1]])
  1688.     s += KMOVD;
  1689.  
  1690.     fyle = column (sq);
  1691.     if (PC1[fyle] == 0)
  1692.     s += KHOPN;
  1693.     if (PC2[fyle] == 0)
  1694.     s += KHOPNX;
  1695.     switch (fyle)
  1696.       {
  1697.       case 5:
  1698.       if (PC1[7] == 0)
  1699.           s += KHOPN;
  1700.       if (PC2[7] == 0)
  1701.           s += KHOPNX;
  1702.       /* Fall through */
  1703.       case 4:
  1704.       case 6:
  1705.       case 0:
  1706.       if (PC1[fyle + 1] == 0)
  1707.           s += KHOPN;
  1708.       if (PC2[fyle + 1] == 0)
  1709.           s += KHOPNX;
  1710.       break;
  1711.       case 2:
  1712.       if (PC1[0] == 0)
  1713.           s += KHOPN;
  1714.       if (PC2[0] == 0)
  1715.           s += KHOPNX;
  1716.       /* Fall through */
  1717.       case 3:
  1718.       case 1:
  1719.       case 7:
  1720.       if (PC1[fyle - 1] == 0)
  1721.           s += KHOPN;
  1722.       if (PC2[fyle - 1] == 0)
  1723.           s += KHOPNX;
  1724.       break;
  1725.       default:
  1726.       /* Impossible! */
  1727.       break;
  1728.       }
  1729.  
  1730.     a2 = (atk2[sq] & 0x4FFF);
  1731.     if (a2 > 0)
  1732.       {
  1733.       a1 = (atk1[sq] & 0x4FFF);
  1734.       if (a1 == 0 || a2 > ctlK + 1)
  1735.         {
  1736.         s += HUNGP;
  1737.         ++hung[c1];
  1738.         }
  1739.       else
  1740.           s += ATAKD;
  1741.       }
  1742.     return (s);
  1743. }
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749. short
  1750. ScorePosition (register short side)
  1751.  
  1752. /*
  1753.  * Perform normal static evaluation of board position. A score is generated
  1754.  * for each piece and these are summed to get a score for each side.
  1755.  */
  1756.  
  1757. {
  1758.     register short score;
  1759.     register short sq, i, xside;
  1760.     short s;
  1761.  
  1762.     UpdateWeights ();
  1763.     xside = side ^ 1;
  1764.     hung[white] = hung[black] = pscore[white] = pscore[black] = 0;
  1765. #ifdef CACHE
  1766.     if (!(hashkey+hashbd) || !ProbeEETable (side, &s))
  1767.       {
  1768. #endif
  1769.       for (c1 = white; c1 <= black; c1++)
  1770.         {
  1771.         c2 = c1 ^ 1;
  1772.         /* atk1 is array of atacks on squares by my side */
  1773.         atk1 = atak[c1];
  1774.         /* atk2 is array of atacks on squares by other side */
  1775.         atk2 = atak[c2];
  1776.         /* same for PC1 and PC2 */
  1777.         PC1 = PawnCnt[c1];
  1778.         PC2 = PawnCnt[c2];
  1779.         for (i = PieceCnt[c1]; i >= 0; i--)
  1780.           {
  1781.               sq = PieceList[c1][i];
  1782.               switch (board[sq])
  1783.             {
  1784.             case pawn:
  1785.                 s = PawnValue (sq, side);
  1786.                 break;
  1787.             case knight:
  1788.                 s = KnightValue (sq, side);
  1789.                 break;
  1790.             case bishop:
  1791.                 s = BishopValue (sq, side);
  1792.                 break;
  1793.             case rook:
  1794.                 s = RookValue (sq, side);
  1795.                 break;
  1796.             case queen:
  1797.                 s = QueenValue (sq, side);
  1798.                 break;
  1799.             case king:
  1800.                 s = KingValue (sq, side);
  1801.                 break;
  1802.             default:
  1803.                 s = 0;
  1804.                 break;
  1805.             }
  1806.               pscore[c1] += s;
  1807.               svalue[sq] = s;
  1808.           }
  1809.         }
  1810.     if (hung[side] > 1)
  1811.     pscore[side] += HUNGX;
  1812.     if (hung[xside] > 1)
  1813.     pscore[xside] += HUNGX;
  1814.  
  1815.     score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  1816. #ifndef NODITHER
  1817.     if (dither)
  1818.       {
  1819.       if (flag.hash)
  1820.           gsrand (starttime + (unsigned int) hashbd);
  1821.       score += urand () % dither;
  1822.       }
  1823. #endif
  1824.     if (score > 0 && pmtl[side] == 0)
  1825.     if (emtl[side] < valueR)
  1826.         score = 0;
  1827.     else if (score < valueR)
  1828.         score /= 2;
  1829.     if (score < 0 && pmtl[xside] == 0)
  1830.     if (emtl[xside] < valueR)
  1831.         score = 0;
  1832.     else if (-score < valueR)
  1833.         score /= 2;
  1834.  
  1835.     if (mtl[xside] == valueK && emtl[side] > valueB)
  1836.     score += 200;
  1837.     if (mtl[side] == valueK && emtl[xside] > valueB)
  1838.     score -= 200;
  1839. #ifdef CACHE
  1840.     if(PUTVAR)PutInEETable(side,score);
  1841. #endif
  1842.     return (score);
  1843. #ifdef CACHE
  1844. }
  1845. else {
  1846. return s;
  1847. }
  1848. #endif
  1849. }
  1850.  
  1851.  
  1852.  
  1853. static inline void
  1854. BlendBoard (const short a[64], const short b[64], short c[64])
  1855. {
  1856.     register int sq, s;
  1857.     s = 10 - stage;
  1858.     for (sq = 0; sq < 64; sq++)
  1859.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  1860. }
  1861.  
  1862.  
  1863. static inline void
  1864. CopyBoard (const short a[64], short b[64])
  1865. {
  1866. #ifndef AMIGA
  1867.     register short *sqa, *sqb;
  1868.  
  1869.     for (sqa = (short *)a, sqb = b; sqa < a + 64;)
  1870.     *sqb++ = *sqa++;
  1871. #else
  1872.  MoveMem128(a,b);
  1873. /* MoveMem(a,b,64*sizeof(short));*/
  1874. #endif
  1875. }
  1876.  
  1877.  
  1878. short __aligned PawnStorm = false;
  1879.  
  1880. void
  1881. ExaminePosition (void)
  1882.  
  1883. /*
  1884.  * This is done one time before the search is started. Set up arrays Mwpawn,
  1885.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  1886.  * to determine the positional value of each piece.
  1887.  */
  1888.  
  1889. {
  1890.     register short i, sq;
  1891.     register short fyle;
  1892.     short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, rank;
  1893. /* update ataks arrays */
  1894.     ataks (white, atak[white]);
  1895.     ataks (black, atak[black]);
  1896. /*    */
  1897.     UpdateWeights ();
  1898. /* initialize Hasxxx */
  1899.     HasKnight[white] = HasKnight[black] = 0;
  1900.     HasBishop[white] = HasBishop[black] = 0;
  1901.     HasRook[white] = HasRook[black] = 0;
  1902.     HasQueen[white] = HasQueen[black] = 0;
  1903.     for (side = white; side <= black; side++)
  1904.     for (i = PieceCnt[side]; i >= 0; i--)
  1905.         switch (board[PieceList[side][i]])
  1906.           {
  1907.           case knight:
  1908.           ++HasKnight[side];
  1909.           break;
  1910.           case bishop:
  1911.           ++HasBishop[side];
  1912.           break;
  1913.           case rook:
  1914.           ++HasRook[side];
  1915.           break;
  1916.           case queen:
  1917.           ++HasQueen[side];
  1918.           break;
  1919.           }
  1920. /* Developed if has moved knights and bishops */
  1921.     if (!Developed[white])
  1922.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  1923.                 board[5] != bishop && board[6] != knight);
  1924.     if (!Developed[black])
  1925.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  1926.                 board[61] != bishop && board[62] != knight);
  1927. /* Pawn Storm */
  1928.     if (!PawnStorm && stage < 6)
  1929.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  1930.              (column (wking) > 4 && column (bking) < 3));
  1931. /* setup base tables */
  1932. #ifndef AMIGA
  1933.     memcpy(Mknight[white],pknight,sizeof(pknight));
  1934.     memcpy(Mknight[black],pknight,sizeof(pknight));
  1935.     memcpy(Mbishop[white],pbishop,sizeof(pbishop));
  1936.     memcpy(Mbishop[black],pbishop,sizeof(pbishop));
  1937. #ifdef notdef
  1938.     CopyBoard (pknight, Mknight[white]);
  1939.     CopyBoard (pknight, Mknight[black]);
  1940.     CopyBoard (pbishop, Mbishop[white]);
  1941.     CopyBoard (pbishop, Mbishop[black]);
  1942. #endif
  1943. #else // use MoveMem128
  1944.  MoveMem128(pknight,Mknight[white]);
  1945.  MoveMem128(pknight,Mknight[black]);
  1946.  MoveMem128(pbishop,Mbishop[white]);
  1947.  MoveMem128(pbishop,Mbishop[black]);
  1948. #endif
  1949. /* linear interpolate on stage    */
  1950. /* Mking = (KingOpening * (10 - stage) + KingEnding * srage) /10  */
  1951.     BlendBoard (KingOpening, KingEnding, Mking[white]);
  1952.     BlendBoard (KingOpening, KingEnding, Mking[black]);
  1953.  
  1954.     for (sq = 0; sq < 64; sq++)
  1955.       {
  1956.       fyle = column (sq);
  1957.       rank = row (sq);
  1958.       wstrong = bstrong = true;
  1959. /* does a black pawn attack to squares in this col from sq to end */
  1960.       for (i = sq; i < 64; i += 8)
  1961.           if (Patak (black, i)) { wstrong = false; break; }
  1962. /* does a white pawn attack to squares in this col from sq to end */
  1963.       for (i = sq; i >= 0; i -= 8)
  1964.           if (Patak (white, i)) { bstrong = false; break; }
  1965. /*     */
  1966.       wpadv = bpadv = PADVNCM;
  1967.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0)) wpadv = PADVNCI;
  1968.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0)) bpadv = PADVNCI;
  1969.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  1970.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  1971.       Mwpawn[sq] += PawnBonus;
  1972.       Mbpawn[sq] += PawnBonus;
  1973. /*     */
  1974.       if (Mvboard[kingP[white]])
  1975.         {
  1976.         if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  1977.             Mwpawn[sq] += PAWNSHIELD;
  1978.         }
  1979.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  1980.           Mwpawn[sq] += PAWNSHIELD / 2;
  1981. /*     */
  1982.       if (Mvboard[kingP[black]])
  1983.         {
  1984.         if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  1985.             Mbpawn[sq] += PAWNSHIELD;
  1986.         }
  1987.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  1988.           Mbpawn[sq] += PAWNSHIELD / 2;
  1989. /*     */
  1990.       if (PawnStorm)
  1991.         {
  1992.         if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  1993.             Mwpawn[sq] += 3 * rank - 21;
  1994.         if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  1995.             Mbpawn[sq] -= 3 * rank;
  1996.         }
  1997. /*     */
  1998.       Mknight[white][sq] += 5 - distance (sq, bking);
  1999.       Mknight[white][sq] += 5 - distance (sq, wking);
  2000.       Mknight[black][sq] += 5 - distance (sq, wking);
  2001.       Mknight[black][sq] += 5 - distance (sq, bking);
  2002. /*     */
  2003.       Mbishop[white][sq] += BishopBonus;
  2004.       Mbishop[black][sq] += BishopBonus;
  2005. /*     */
  2006.       for (i = PieceCnt[black]; i >= 0; i--)
  2007.           if (distance (sq, PieceList[black][i]) < 3)
  2008.           Mknight[white][sq] += KNIGHTPOST;
  2009.       for (i = PieceCnt[white]; i >= 0; i--)
  2010.           if (distance (sq, PieceList[white][i]) < 3)
  2011.           Mknight[black][sq] += KNIGHTPOST;
  2012. /*     */
  2013.       if (wstrong)
  2014.           Mknight[white][sq] += KNIGHTSTRONG;
  2015.       if (bstrong)
  2016.           Mknight[black][sq] += KNIGHTSTRONG;
  2017.       if (wstrong)
  2018.           Mbishop[white][sq] += BISHOPSTRONG;
  2019.       if (bstrong)
  2020.           Mbishop[black][sq] += BISHOPSTRONG;
  2021. /*     */
  2022.  
  2023.       if (HasBishop[white] == 2)
  2024.           Mbishop[white][sq] += 8;
  2025.       if (HasBishop[black] == 2)
  2026.           Mbishop[black][sq] += 8;
  2027.       if (HasKnight[white] == 2)
  2028.           Mknight[white][sq] += 5;
  2029.       if (HasKnight[black] == 2)
  2030.           Mknight[black][sq] += 5;
  2031. /*     */
  2032.  
  2033.       Kfield[white][sq] = Kfield[black][sq] = 0;
  2034.       if (distance (sq, wking) == 1)
  2035.           Kfield[black][sq] = KATAK;
  2036.       if (distance (sq, bking) == 1)
  2037.           Kfield[white][sq] = KATAK;
  2038. /*     */
  2039.       Pd = 0;
  2040.       for (k = 0; k <= PieceCnt[white]; k++)
  2041.         {
  2042.         i = PieceList[white][k];
  2043.         if (board[i] == pawn)
  2044.           {
  2045.               pp = true;
  2046.               z = i + ((row (i) == 6) ? 8 : 16);
  2047.               for (j = i + 8; j < 64; j += 8)
  2048.               if (Patak (black, j) || board[j] == pawn)
  2049.                 {
  2050.                 pp = false;
  2051.                 break;
  2052.                 }
  2053.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  2054.           }
  2055.         }
  2056. /*     */
  2057.       for (k = 0; k <= PieceCnt[black]; k++)
  2058.         {
  2059.         i = PieceList[black][k];
  2060.         if (board[i] == pawn)
  2061.           {
  2062.               pp = true;
  2063.               z = i - ((row (i) == 1) ? 8 : 16);
  2064.               for (j = i - 8; j >= 0; j -= 8)
  2065.               if (Patak (white, j) || board[j] == pawn)
  2066.                 {
  2067.                 pp = false;
  2068.                 break;
  2069.                 }
  2070.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  2071.           }
  2072.         }
  2073. /*     */
  2074.       if (Pd != 0)
  2075.         {
  2076.         val = (Pd * stage2) / 10;
  2077.         Mking[white][sq] -= val;
  2078.         Mking[black][sq] -= val;
  2079.         }
  2080.       }
  2081. }
  2082.  
  2083.  
  2084. void
  2085. UpdateWeights (void)
  2086.  
  2087. /*
  2088.  * If material balance has changed, determine the values for the positional
  2089.  * evaluation terms.
  2090.  */
  2091.  
  2092. {
  2093.     register short s1;
  2094.  
  2095.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  2096.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  2097.     tmtl = emtl[white] + emtl[black];
  2098.     s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  2099.     if (s1 != stage)
  2100.       {
  2101.       stage = s1;
  2102.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  2103.       PEDRNK2B = -15;    /* centre pawn on 2nd rank & blocked */
  2104.       PBLOK = -4;        /* blocked backward pawn */
  2105.       PDOUBLED = -14;    /* doubled pawn */
  2106.       PWEAKH = -4;        /* weak pawn on half open file */
  2107.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  2108.       PADVNCM = 10;        /* advanced pawn multiplier */
  2109.       PADVNCI = 7;        /* muliplier for isolated pawn */
  2110.       PawnBonus = stage;
  2111.  
  2112.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  2113.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  2114.  
  2115.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  2116.       BishopBonus = BBONUS * stage;
  2117.  
  2118.       RHOPN = 10;        /* rook on half open file */
  2119.       RHOPNX = 4;
  2120.       RookBonus = RBONUS * stage;
  2121.  
  2122.       XRAY = 8;        /* Xray attack on piece */
  2123.       PINVAL = 10;        /* Pin */
  2124.  
  2125.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  2126.       KHOPNX = KHOPN / 2;
  2127.       KCASTLD = 10 - stage;
  2128.       KMOVD = -40 / (stage + 1);    /* king moved before castling */
  2129.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  2130.       KSFTY = ((stage < 8) ? (KINGSAFETY - 4 * stage) : 0);
  2131.  
  2132.       ATAKD = -6;        /* defender > attacker */
  2133.       HUNGP = -12;        /* each hung piece */
  2134.       HUNGX = -18;        /* extra for >1 hung piece */
  2135.       }
  2136. }
  2137.  
  2138. #ifdef REALOLDEVAL // pre 4pl67 code
  2139. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  2140.  
  2141. /*
  2142.  * Inputs are:
  2143.  * pmtl[side] - value of pawns
  2144.  * mtl[side]  - value of all material
  2145.  * emtl[side] - vaule of all material - value of pawns - value of king
  2146.  * hung[side] - count of hung pieces
  2147.  * Tscore[ply] - search tree score for ply
  2148.  * ply
  2149.  * Pscore[ply] - positional score for ply ply
  2150.  * INCscore    - bonus score or penalty for certain positions
  2151.  * slk - single lone king flag
  2152.  * Sdepth - search goal depth
  2153.  * xwndw - evaluation window about alpha/beta
  2154.  * EWNDW - second evaluation window about alpha/beta
  2155.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  2156.  */
  2157.  
  2158. inline
  2159. int
  2160. ScoreKPK (ARGSZ int side,
  2161.       ARGSZ int winner,
  2162.       ARGSZ int loser,
  2163.       ARGSZ int king1,
  2164.       ARGSZ int king2,
  2165.       ARGSZ int sq)
  2166.  
  2167. /*
  2168.  * Score King and Pawns versus King endings.
  2169.  */
  2170.  
  2171. {
  2172.     register short s, r;
  2173.  
  2174.     s = ((PieceCnt[winner] == 1) ? 50 : 120);
  2175.     if (winner == white)
  2176.       {
  2177.       r = row (sq) - ((side == loser) ? 1 : 0);
  2178.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  2179.           s += 10 * row (sq);
  2180.       else
  2181.           s = 500 + 50 * row (sq);
  2182.       if (row (sq) < 6)
  2183.           sq += 16;
  2184.       else if (row (sq) == 6)
  2185.           sq += 8;
  2186.       }
  2187.     else
  2188.       {
  2189.       r = row (sq) + ((side == loser) ? 1 : 0);
  2190.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  2191.           s += 10 * (7 - row (sq));
  2192.       else
  2193.           s = 500 + 50 * (7 - row (sq));
  2194.       if (row (sq) > 1)
  2195.           sq -= 16;
  2196.       else if (row (sq) == 1)
  2197.           sq -= 8;
  2198.       }
  2199.     s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  2200.     return (s);
  2201. }
  2202.  
  2203.  
  2204. inline
  2205. int
  2206. ScoreKBNK (ARGSZ int winner, ARGSZ int king1, ARGSZ int king2)
  2207.  
  2208.  
  2209. /*
  2210.  * Score King+Bishop+Knight versus King endings. This doesn't work all that
  2211.  * well but it's better than nothing.
  2212.  */
  2213.  
  2214. {
  2215.     register short s, sq, KBNKsq = 0;
  2216.  
  2217.     for (sq = 0; sq < 64; sq++)
  2218.     if (board[sq] == bishop)
  2219.         KBNKsq = (((row (sq) % 2) == (column (sq) % 2)) ? 0 : 7);
  2220.  
  2221.     s = emtl[winner] - 300;
  2222.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  2223.     s -= ((taxicab (king1, king2) + distance (PieceList[winner][1], king2) + distance (PieceList[winner][2], king2)));
  2224.     return (s);
  2225. }
  2226.  
  2227.  
  2228.  
  2229.  
  2230. int
  2231. evaluate (INTSIZE int side,
  2232.       INTSIZE int ply,
  2233.       INTSIZE int alpha,
  2234.       INTSIZE int beta,
  2235.       INTSIZE int INCscore,
  2236.       short int *InChk)    /* output Check flag */
  2237.  
  2238. /*
  2239.  * Compute an estimate of the score by adding the positional score from the
  2240.  * previous ply to the material difference. If this score falls inside a
  2241.  * window which is 180 points wider than the alpha-beta window (or within a
  2242.  * 50 point window during quiescence search) call ScorePosition() to
  2243.  * determine a score, otherwise return the estimated score. If one side has
  2244.  * only a king and the other either has no pawns or no pieces then the
  2245.  * function ScoreLoneKing() is called.
  2246.  */
  2247.  
  2248. {
  2249.     register short xside;
  2250.     register short int slk;
  2251.     short s;
  2252. /*    int HEVAL=false; seems useless to me! */
  2253.  
  2254.     xside = side ^ 1;
  2255.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  2256.     hung[white] = hung[black] = 0;
  2257.     slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  2258.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  2259.  
  2260.           /* should we use the estimete or score the position */
  2261.     if (!(slk) && (ply == 1 ||
  2262. #ifdef CACHE
  2263.         (/*HEVAL =*/ CheckEETable (side)) ||
  2264. #endif
  2265.     (Sdepth ==  ply) || 
  2266.         (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30)) )))
  2267.       {
  2268.       /* score the position */
  2269.       ataks (side, atak[side]);
  2270.       if (Anyatak (side, PieceList[xside][0])){
  2271.       ataks (xside, atak[xside]);
  2272.       *InChk = Anyatak (xside, PieceList[side][0]);
  2273.           return (10001 - ply);
  2274.       }
  2275.       ataks (xside, atak[xside]);
  2276.       *InChk = Anyatak (xside, PieceList[side][0]);
  2277. #ifndef BAREBONES 
  2278.       EvalNodes++;
  2279. #endif
  2280.     if(ply>4)PUTVAR=true;
  2281.           s = ScorePosition (side);
  2282.     PUTVAR=false;
  2283.       }
  2284.     else
  2285.       {
  2286.       /* use the estimate but look at check and slk */
  2287.       *InChk = SqAtakd (PieceList[side][0], xside);
  2288.       if (SqAtakd (PieceList[xside][0], side)){
  2289.           return (10001 - ply);
  2290.       }
  2291.  
  2292.       if (slk) {
  2293.         if (ply>4) PUTVAR=true;
  2294.             s = ScoreLoneKing (side);
  2295.             PUTVAR=false;
  2296.             }
  2297.       }
  2298.  
  2299.     Pscore[ply] = s - mtl[side] + mtl[xside];
  2300.     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  2301.     return (s);
  2302. }
  2303.  
  2304. inline
  2305. int
  2306. BRscan (ARGSZ int sq, short int *mob)
  2307.  
  2308. /*
  2309.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  2310.  * hung[] array if a pin is found.
  2311.  */
  2312. {
  2313.     register unsigned char *ppos, *pdir;
  2314.     register short s, mobx;
  2315.     register short u, pin;
  2316.     short piece, *Kf;
  2317.     mobx = s = 0;
  2318.     Kf = Kfield[c1];
  2319.     piece = board[sq];
  2320.     ppos = nextpos[piece][sq];
  2321.     pdir = nextdir[piece][sq];
  2322.     u = ppos[sq];
  2323.     pin = -1;            /* start new direction */
  2324.     do
  2325.       {
  2326.       s += Kf[u];
  2327.       if (color[u] == neutral)
  2328.         {
  2329.         mobx++;
  2330.         if (ppos[u] == pdir[u])
  2331.             pin = -1;    /* oops new direction */
  2332.         u = ppos[u];
  2333.         }
  2334.       else if (pin < 0)
  2335.         {
  2336.         if (board[u] == pawn || board[u] == king)
  2337.             u = pdir[u];
  2338.         else
  2339.           {
  2340.               if (ppos[u] != pdir[u])
  2341.               pin = u;    /* not on the edge and on to find a pin */
  2342.               u = ppos[u];
  2343.           }
  2344.         }
  2345.       else
  2346.         {
  2347.         if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  2348.           {
  2349.               if (color[pin] == c2)
  2350.             {
  2351.                 s += PINVAL;
  2352.                 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  2353.                 ++hung[c2];
  2354.             }
  2355.               else
  2356.               s += XRAY;
  2357.           }
  2358.         pin = -1;    /* new direction */
  2359.         u = pdir[u];
  2360.         }
  2361.       }
  2362.     while (u != sq);
  2363.     *mob = mobx;
  2364.     return s;
  2365. }
  2366.  
  2367. inline
  2368. short int
  2369. KingScan (ARGSZ int sq)
  2370.  
  2371. /*
  2372.  * Assign penalties if king can be threatened by checks, if squares near the
  2373.  * king are controlled by the enemy (especially the queen), or if there are
  2374.  * no pawns near the king. The following must be true: board[sq] == king c1
  2375.  * == color[sq] c2 == otherside[c1]
  2376.  */
  2377.  
  2378. #define ScoreThreat \
  2379.     if (color[u] != c2)\
  2380.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  2381.       else s -= 3
  2382.  
  2383. {
  2384.     register short cnt;
  2385.     register unsigned char *ppos, *pdir;
  2386.     register short int s;
  2387.     register short u;
  2388.     short int ok;
  2389.  
  2390.     s = 0;
  2391.     cnt = 0;
  2392.     if (HasBishop[c2] || HasQueen[c2])
  2393.       {
  2394.       ppos = nextpos[bishop][sq];
  2395.       pdir = nextdir[bishop][sq];
  2396.       u = ppos[sq];
  2397.       do
  2398.         {
  2399.         if (atk2[u] & ctlBQ)
  2400.             ScoreThreat;
  2401.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  2402.         }
  2403.       while (u != sq);
  2404.       }
  2405.     if (HasRook[c2] || HasQueen[c2])
  2406.       {
  2407.       ppos = nextpos[rook][sq];
  2408.       pdir = nextdir[rook][sq];
  2409.       u = ppos[sq];
  2410.       do
  2411.         {
  2412.         if (atk2[u] & ctlRQ)
  2413.             ScoreThreat;
  2414.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  2415.         }
  2416.       while (u != sq);
  2417.       }
  2418.     if (HasKnight[c2])
  2419.       {
  2420.       pdir = nextdir[knight][sq];
  2421.       u = pdir[sq];
  2422.       do
  2423.         {
  2424.         if (atk2[u] & ctlNN)
  2425.             ScoreThreat;
  2426.         u = pdir[u];
  2427.         }
  2428.       while (u != sq);
  2429.       }
  2430.     s += (KSFTY * KTHRT[cnt]) / 16;
  2431.  
  2432.     cnt = 0;
  2433.     ok = false;
  2434.     pdir = nextpos[king][sq];
  2435.     u = pdir[sq];
  2436.     do
  2437.       {
  2438.       if (board[u] == pawn)
  2439.           ok = true;
  2440.       if (atk2[u] > atk1[u])
  2441.         {
  2442.         ++cnt;
  2443.         if (atk2[u] & ctlQ)
  2444.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  2445.             s -= 4 * KSFTY;
  2446.         }
  2447.       u = pdir[u];
  2448.       }
  2449.     while (u != sq);
  2450.     if (!ok)
  2451.     s -= KSFTY;
  2452.     if (cnt > 1)
  2453.     s -= (KSFTY);
  2454.     return (s);
  2455. }
  2456.  
  2457. inline
  2458. int
  2459. trapped (ARGSZ int sq)
  2460.  
  2461. /*
  2462.  * See if the attacked piece has unattacked squares to move to. The following
  2463.  * must be true: c1 == color[sq] c2 == otherside[c1]
  2464.  */
  2465.  
  2466. {
  2467.     register short u;
  2468.     register unsigned char *ppos, *pdir;
  2469.     register short int piece;
  2470.  
  2471.     piece = board[sq];
  2472.     ppos = nextpos[ptype[c1][piece]][sq];
  2473.     pdir = nextdir[ptype[c1][piece]][sq];
  2474.     if (piece == pawn)
  2475.       {
  2476.       u = ppos[sq];        /* follow no captures thread */
  2477.       if (color[u] == neutral)
  2478.         {
  2479.         if (atk1[u] >= atk2[u])
  2480.             return (false);
  2481.         if (atk2[u] < ctlP)
  2482.           {
  2483.               u = ppos[u];
  2484.               if (color[u] == neutral && atk1[u] >= atk2[u])
  2485.               return (false);
  2486.           }
  2487.         }
  2488.       u = pdir[sq];        /* follow captures thread */
  2489.       if (color[u] == c2)
  2490.           return (false);
  2491.       u = pdir[u];
  2492.       if (color[u] == c2)
  2493.           return (false);
  2494.       }
  2495.     else
  2496.       {
  2497.       u = ppos[sq];
  2498.       do
  2499.         {
  2500.         if (color[u] != c1)
  2501.             if (atk2[u] == 0 || board[u] >= piece)
  2502.             return (false);
  2503.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  2504.         }
  2505.       while (u != sq);
  2506.       }
  2507.     return (true);
  2508. }
  2509.  
  2510.  
  2511. static inline int
  2512. PawnValue (ARGSZ int sq, ARGSZ int side)
  2513. /*
  2514.  * Calculate the positional value for a pawn on 'sq'.
  2515.  */
  2516.  
  2517. {
  2518.     register short fyle, rank;
  2519.     register short j, s, a1, a2, in_square, r, e;
  2520.  
  2521.     a1 = (atk1[sq] & 0x4FFF);
  2522.     a2 = (atk2[sq] & 0x4FFF);
  2523.     rank = row (sq);
  2524.     fyle = column (sq);
  2525.     s = 0;
  2526.     if (c1 == white)
  2527.       {
  2528.       s = Mwpawn[sq];
  2529.       if ((sq == 11 && color[19] != neutral)
  2530.           || (sq == 12 && color[20] != neutral))
  2531.           s += PEDRNK2B;
  2532.       if ((fyle == 0 || PC1[fyle - 1] == 0)
  2533.           && (fyle == 7 || PC1[fyle + 1] == 0))
  2534.           s += ISOLANI[fyle];
  2535.       else if (PC1[fyle] > 1)
  2536.           s += PDOUBLED;
  2537.       if (a1 < ctlP && atk1[sq + 8] < ctlP)
  2538.         {
  2539.         s += BACKWARD[a2 & 0xFF];
  2540.         if (PC2[fyle] == 0)
  2541.             s += PWEAKH;
  2542.         if (color[sq + 8] != neutral)
  2543.             s += PBLOK;
  2544.         }
  2545.       if (PC2[fyle] == 0)
  2546.         {
  2547.         if (side == black)
  2548.             r = rank - 1;
  2549.         else
  2550.             r = rank;
  2551.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  2552.         if (a2 == 0 || side == white)
  2553.             e = 0;
  2554.         else
  2555.             e = 1;
  2556.         for (j = sq + 8; j < 64; j += 8)
  2557.             if (atk2[j] >= ctlP)
  2558.               {
  2559.               e = 2;
  2560.               break;
  2561.               }
  2562.             else if (atk2[j] > 0 || color[j] != neutral)
  2563.             e = 1;
  2564.         if (e == 2)
  2565.             s += (stage * PassedPawn3[rank]) / 10;
  2566.         else if (in_square || e == 1)
  2567.             s += (stage * PassedPawn2[rank]) / 10;
  2568.         else if (emtl[black] > 0)
  2569.             s += (stage * PassedPawn1[rank]) / 10;
  2570.         else
  2571.             s += PassedPawn0[rank];
  2572.         }
  2573.       }
  2574.     else if (c1 == black)
  2575.       {
  2576.       s = Mbpawn[sq];
  2577.       if ((sq == 51 && color[43] != neutral)
  2578.           || (sq == 52 && color[44] != neutral))
  2579.           s += PEDRNK2B;
  2580.       if ((fyle == 0 || PC1[fyle - 1] == 0) &&
  2581.           (fyle == 7 || PC1[fyle + 1] == 0))
  2582.           s += ISOLANI[fyle];
  2583.       else if (PC1[fyle] > 1)
  2584.           s += PDOUBLED;
  2585.       if (a1 < ctlP && atk1[sq - 8] < ctlP)
  2586.         {
  2587.         s += BACKWARD[a2 & 0xFF];
  2588.         if (PC2[fyle] == 0)
  2589.             s += PWEAKH;
  2590.         if (color[sq - 8] != neutral)
  2591.             s += PBLOK;
  2592.         }
  2593.       if (PC2[fyle] == 0)
  2594.         {
  2595.         if (side == white)
  2596.             r = rank + 1;
  2597.         else
  2598.             r = rank;
  2599.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  2600.         if (a2 == 0 || side == black)
  2601.             e = 0;
  2602.         else
  2603.             e = 1;
  2604.         for (j = sq - 8; j >= 0; j -= 8)
  2605.             if (atk2[j] >= ctlP)
  2606.               {
  2607.               e = 2;
  2608.               break;
  2609.               }
  2610.             else if (atk2[j] > 0 || color[j] != neutral)
  2611.             e = 1;
  2612.         if (e == 2)
  2613.             s += (stage * PassedPawn3[7 - rank]) / 10;
  2614.         else if (in_square || e == 1)
  2615.             s += (stage * PassedPawn2[7 - rank]) / 10;
  2616.         else if (emtl[white] > 0)
  2617.             s += (stage * PassedPawn1[7 - rank]) / 10;
  2618.         else
  2619.             s += PassedPawn0[7 - rank];
  2620.         }
  2621.       }
  2622.     if (a2 > 0)
  2623.       {
  2624.       if (a1 == 0 || a2 > ctlP + 1)
  2625.         {
  2626.         s += HUNGP;
  2627.         if (trapped (sq))
  2628.             hung[c1] += 2;
  2629.         hung[c1]++;
  2630.         }
  2631.       else if (a2 > a1)
  2632.           s += ATAKD;
  2633.       }
  2634.     return (s);
  2635. }
  2636.  
  2637. inline
  2638. int
  2639. KnightValue (ARGSZ int sq)
  2640.  
  2641. /*
  2642.  * Calculate the positional value for a knight on 'sq'.
  2643.  */
  2644.  
  2645. {
  2646.     register short s, a2, a1;
  2647.  
  2648.     s = Mknight[c1][sq];
  2649.     a2 = (atk2[sq] & 0x4FFF);
  2650.     if (a2 > 0)
  2651.       {
  2652.       a1 = (atk1[sq] & 0x4FFF);
  2653.       if (a1 == 0 || a2 > ctlBN + 1)
  2654.         {
  2655.         s += HUNGP;
  2656.         if (trapped (sq))
  2657.             hung[c1] += 2;
  2658.         hung[c1]++;
  2659.         }
  2660.       else if (a2 >= ctlBN || a1 < ctlP)
  2661.           s += ATAKD;
  2662.       }
  2663.     return (s);
  2664. }
  2665.  
  2666. inline
  2667. int
  2668. BishopValue (ARGSZ int sq)
  2669.  
  2670. /*
  2671.  * Calculate the positional value for a bishop on 'sq'.
  2672.  */
  2673.  
  2674. {
  2675.     register short s;
  2676.     register short a2, a1;
  2677.     short mob;
  2678.  
  2679.     s = Mbishop[c1][sq];
  2680.     s += BRscan (sq, &mob);
  2681.     s += BMBLTY[mob];
  2682.     a2 = (atk2[sq] & 0x4FFF);
  2683.     if (a2 > 0)
  2684.       {
  2685.       a1 = (atk1[sq] & 0x4FFF);
  2686.       if (a1 == 0 || a2 > ctlBN + 1)
  2687.         {
  2688.         s += HUNGP;
  2689.         if (trapped (sq))
  2690.             hung[c1] += 2;
  2691.         hung[c1]++;
  2692.         }
  2693.       else if (a2 >= ctlBN || a1 < ctlP)
  2694.           s += ATAKD;
  2695.       }
  2696.     return (s);
  2697. }
  2698.  
  2699. inline
  2700. int
  2701. RookValue (ARGSZ int sq)
  2702.  
  2703. /*
  2704.  * Calculate the positional value for a rook on 'sq'.
  2705.  */
  2706.  
  2707. {
  2708.     register short s;
  2709.     register short fyle, a2, a1;
  2710.     short mob;
  2711.  
  2712.     s = RookBonus;
  2713.     s += BRscan (sq, &mob);
  2714.     s += RMBLTY[mob];
  2715.     fyle = column (sq);
  2716.     if (PC1[fyle] == 0)
  2717.      {
  2718.     s += RHOPN;
  2719.             if (PC2[fyle] == 0)
  2720.             s += RHOPNX;
  2721.      }
  2722.     if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  2723.     s += 10;
  2724.     if (stage > 2)
  2725.     s += 14 - taxicab (sq, EnemyKing);
  2726.     a2 = (atk2[sq] & 0x4FFF);
  2727.     if (a2 > 0)
  2728.       {
  2729.       a1 = (atk1[sq] & 0x4FFF);
  2730.       if (a1 == 0 || a2 > ctlR + 1)
  2731.         {
  2732.         s += HUNGP;
  2733.         if (trapped (sq))
  2734.             hung[c1] += 2;
  2735.         hung[c1]++;
  2736.         }
  2737.       else if (a2 >= ctlR || a1 < ctlP)
  2738.           s += ATAKD;
  2739.       }
  2740.     return (s);
  2741. }
  2742.  
  2743. inline
  2744. int
  2745. QueenValue (ARGSZ int sq)
  2746.  
  2747. /*
  2748.  * Calculate the positional value for a queen on 'sq'.
  2749.  */
  2750.  
  2751. {
  2752.     register short s, a2, a1;
  2753.  
  2754.     s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  2755.     if (stage > 2)
  2756.     s += 14 - taxicab (sq, EnemyKing);
  2757.     a2 = (atk2[sq] & 0x4FFF);
  2758.     if (a2 > 0)
  2759.       {
  2760.       a1 = (atk1[sq] & 0x4FFF);
  2761.       if (a1 == 0 || a2 > ctlQ + 1)
  2762.         {
  2763.         s += HUNGP;
  2764.         if (trapped (sq))
  2765.             hung[c1] += 2;
  2766.         hung[c1]++;
  2767.         }
  2768.       else if (a2 >= ctlQ || a1 < ctlP)
  2769.           s += ATAKD;
  2770.       }
  2771.     return (s);
  2772. }
  2773.  
  2774. inline
  2775. int
  2776. KingValue (ARGSZ int sq, ARGSZ int side)
  2777.  
  2778. /*
  2779.  * Calculate the positional value for a king on 'sq'.
  2780.  */
  2781.  
  2782. {
  2783.     register short s;
  2784.     register short fyle;
  2785.     short int a2, a1;
  2786.     s = (emtl[side ^ 1] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  2787.     if (KSFTY > 0)
  2788.     if (Developed[c2] || stage > 0)
  2789.         s += KingScan (sq);
  2790.     if (castld[c1])
  2791.     s += KCASTLD;
  2792.     else if (Mvboard[kingP[c1]])
  2793.     s += KMOVD;
  2794.  
  2795.     fyle = column (sq);
  2796.     if (PC1[fyle] == 0)
  2797.     s += KHOPN;
  2798.     if (PC2[fyle] == 0)
  2799.     s += KHOPNX;
  2800.     switch (fyle)
  2801.       {
  2802.       case 5:
  2803.       if (PC1[7] == 0)
  2804.           s += KHOPN;
  2805.       if (PC2[7] == 0)
  2806.           s += KHOPNX;
  2807.       /* Fall through */
  2808.       case 4:
  2809.       case 6:
  2810.       case 0:
  2811.       if (PC1[fyle + 1] == 0)
  2812.           s += KHOPN;
  2813.       if (PC2[fyle + 1] == 0)
  2814.           s += KHOPNX;
  2815.       break;
  2816.       case 2:
  2817.       if (PC1[0] == 0)
  2818.           s += KHOPN;
  2819.       if (PC2[0] == 0)
  2820.           s += KHOPNX;
  2821.       /* Fall through */
  2822.       case 3:
  2823.       case 1:
  2824.       case 7:
  2825.       if (PC1[fyle - 1] == 0)
  2826.           s += KHOPN;
  2827.       if (PC2[fyle - 1] == 0)
  2828.           s += KHOPNX;
  2829.       break;
  2830.       default:
  2831.       /* Impossible! */
  2832.       break;
  2833.       }
  2834.  
  2835.     a2 = (atk2[sq] & 0x4FFF);
  2836.     if (a2 > 0)
  2837.       {
  2838.       a1 = (atk1[sq] & 0x4FFF);
  2839.       if (a1 == 0 || a2 > ctlK + 1)
  2840.         {
  2841.         s += HUNGP;
  2842.         ++hung[c1];
  2843.         }
  2844.       else
  2845.           s += ATAKD;
  2846.       }
  2847.     return (s);
  2848. }
  2849.  
  2850.  
  2851. short int
  2852. ScorePosition (register short int side)
  2853.  
  2854. /*
  2855.  * Perform normal static evaluation of board position. A score is generated
  2856.  * for each piece and these are summed to get a score for each side.
  2857.  */
  2858.  
  2859. {
  2860.     register short int score;
  2861.     register short sq, i, xside;
  2862.     short int s;
  2863.  
  2864.     UpdateWeights ();
  2865.     xside = side ^ 1;
  2866.     hung[white] = hung[black] = pscore[white] = pscore[black] = 0;
  2867. #ifdef CACHE
  2868.     if (!ProbeEETable (side, &s))
  2869.       {
  2870. #endif
  2871.       for (c1 = white; c1 <= black; c1++)
  2872.         {
  2873.         c2 = c1 ^ 1;
  2874.         /* atk1 is array of atacks on squares by my side */
  2875.         atk1 = atak[c1];
  2876.         /* atk2 is array of atacks on squares by other side */
  2877.         atk2 = atak[c2];
  2878.         /* same for PC1 and PC2 */
  2879.         PC1 = PawnCnt[c1];
  2880.         PC2 = PawnCnt[c2];
  2881.         for (i = PieceCnt[c1]; i >= 0; i--)
  2882.           {
  2883.               sq = PieceList[c1][i];
  2884.               switch (board[sq])
  2885.             {
  2886.             case pawn:
  2887.                 s = PawnValue (sq, side);
  2888.                 break;
  2889.             case knight:
  2890.                 s = KnightValue (sq);
  2891.                 break;
  2892.             case bishop:
  2893.                 s = BishopValue (sq);
  2894.                 break;
  2895.             case rook:
  2896.                 s = RookValue (sq);
  2897.                 break;
  2898.             case queen:
  2899.                 s = QueenValue (sq);
  2900.                 break;
  2901.             case king:
  2902.                 s = KingValue (sq, side);
  2903.                 break;
  2904.             default:
  2905.                 s = 0;
  2906.                 break;
  2907.             }
  2908.               pscore[c1] += s;
  2909.               svalue[sq] = s;
  2910.           }
  2911.         }
  2912.     if (hung[side] > 1)
  2913.     pscore[side] += HUNGX;
  2914.     if (hung[xside] > 1)
  2915.     pscore[xside] += HUNGX;
  2916.  
  2917.     score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  2918.     if (dither)
  2919.       {
  2920.       if (flag.hash)
  2921.           gsrand (starttime + (unsigned int) hashbd);
  2922.       score += urand () % dither;
  2923.       }
  2924.  
  2925.     if (score > 0 && pmtl[side] == 0)
  2926.     if (emtl[side] < valueR)
  2927.         score = 0;
  2928.     else if (score < valueR)
  2929.         score /= 2;
  2930.     if (score < 0 && pmtl[xside] == 0)
  2931.     if (emtl[xside] < valueR)
  2932.         score = 0;
  2933.     else if (-score < valueR)
  2934.         score /= 2;
  2935.  
  2936.     if (mtl[xside] == valueK && emtl[side] > valueB)
  2937.     score += 200;
  2938.     if (mtl[side] == valueK && emtl[xside] > valueB)
  2939.     score -= 200;
  2940. #ifdef CACHE
  2941.     if(PUTVAR)PutInEETable(side,score);
  2942. #endif
  2943.     return (score);
  2944. #ifdef CACHE
  2945. }
  2946. else {
  2947. return s;
  2948. }
  2949. #endif
  2950. }
  2951.  
  2952.  
  2953. static inline void
  2954. BlendBoard (const short int a[64], const short int b[64], short int c[64])
  2955. {
  2956.     register int sq, s;
  2957.     s = 10 - stage;
  2958.     for (sq = 0; sq < 64; sq++)
  2959.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  2960. }
  2961.  
  2962.  
  2963. static inline void
  2964. CopyBoard (const short int a[64], short int b[64])
  2965. {
  2966. #ifndef AMIGA
  2967.     register short *sqa, *sqb;
  2968.  
  2969.     for (sqa = (short *)a, sqb = b; sqa < a + 64;)
  2970.     *sqb++ = *sqa++;
  2971. #else
  2972.  MoveMem128(a,b);
  2973. /* MoveMem(a,b,64*sizeof(short));*/
  2974. #endif
  2975. }
  2976.  
  2977.  
  2978. void
  2979. ExaminePosition (void)
  2980.  
  2981. /*
  2982.  * This is done one time before the search is started. Set up arrays Mwpawn,
  2983.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  2984.  * to determine the positional value of each piece.
  2985.  */
  2986.  
  2987. {
  2988.     register short i, sq;
  2989.     register short fyle;
  2990.     short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, rank;
  2991.     static short PawnStorm = false;
  2992.  
  2993.     ataks (white, atak[white]);
  2994.     ataks (black, atak[black]);
  2995.     UpdateWeights ();
  2996.     HasKnight[white] = HasKnight[black] = 0;
  2997.     HasBishop[white] = HasBishop[black] = 0;
  2998.     HasRook[white] = HasRook[black] = 0;
  2999.     HasQueen[white] = HasQueen[black] = 0;
  3000.     for (side = white; side <= black; side++)
  3001.     for (i = PieceCnt[side]; i >= 0; i--)
  3002.         switch (board[PieceList[side][i]])
  3003.           {
  3004.           case knight:
  3005.           ++HasKnight[side];
  3006.           break;
  3007.           case bishop:
  3008.           ++HasBishop[side];
  3009.           break;
  3010.           case rook:
  3011.           ++HasRook[side];
  3012.           break;
  3013.           case queen:
  3014.           ++HasQueen[side];
  3015.           break;
  3016.           }
  3017.     if (!Developed[white])
  3018.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  3019.                 board[5] != bishop && board[6] != knight);
  3020.     if (!Developed[black])
  3021.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  3022.                 board[61] != bishop && board[62] != knight);
  3023.     if (!PawnStorm && stage < 5)
  3024.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  3025.              (column (wking) > 4 && column (bking) < 3));
  3026.  
  3027.     CopyBoard (pknight, Mknight[white]);
  3028.     CopyBoard (pknight, Mknight[black]);
  3029.     CopyBoard (pbishop, Mbishop[white]);
  3030.     CopyBoard (pbishop, Mbishop[black]);
  3031.     BlendBoard (KingOpening, KingEnding, Mking[white]);
  3032.     BlendBoard (KingOpening, KingEnding, Mking[black]);
  3033.  
  3034.     for (sq = 0; sq < 64; sq++)
  3035.       {
  3036.       fyle = column (sq);
  3037.       rank = row (sq);
  3038.       wstrong = bstrong = true;
  3039.       for (i = sq; i < 64; i += 8)
  3040.           if (Patak (black, i))
  3041.         {
  3042.             wstrong = false;
  3043.             break;
  3044.         }
  3045.       for (i = sq; i >= 0; i -= 8)
  3046.           if (Patak (white, i))
  3047.         {
  3048.             bstrong = false;
  3049.             break;
  3050.         }
  3051.       wpadv = bpadv = PADVNCM;
  3052.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0))
  3053.           wpadv = PADVNCI;
  3054.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0))
  3055.           bpadv = PADVNCI;
  3056.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  3057.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  3058.       Mwpawn[sq] += PawnBonus;
  3059.       Mbpawn[sq] += PawnBonus;
  3060.       if (Mvboard[kingP[white]])
  3061.         {
  3062.         if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  3063.             Mwpawn[sq] += PAWNSHIELD;
  3064.         }
  3065.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  3066.           Mwpawn[sq] += PAWNSHIELD / 2;
  3067.       if (Mvboard[kingP[black]])
  3068.         {
  3069.         if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  3070.             Mbpawn[sq] += PAWNSHIELD;
  3071.         }
  3072.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  3073.           Mbpawn[sq] += PAWNSHIELD / 2;
  3074.       if (PawnStorm)
  3075.         {
  3076.         if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  3077.             Mwpawn[sq] += 3 * rank - 21;
  3078.         if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  3079.             Mbpawn[sq] -= 3 * rank;
  3080.         }
  3081.       Mknight[white][sq] += 5 - distance (sq, bking);
  3082.       Mknight[white][sq] += 5 - distance (sq, wking);
  3083.       Mknight[black][sq] += 5 - distance (sq, wking);
  3084.       Mknight[black][sq] += 5 - distance (sq, bking);
  3085.       Mbishop[white][sq] += BishopBonus;
  3086.       Mbishop[black][sq] += BishopBonus;
  3087.       for (i = PieceCnt[black]; i >= 0; i--)
  3088.           if (distance (sq, PieceList[black][i]) < 3)
  3089.           Mknight[white][sq] += KNIGHTPOST;
  3090.       for (i = PieceCnt[white]; i >= 0; i--)
  3091.           if (distance (sq, PieceList[white][i]) < 3)
  3092.           Mknight[black][sq] += KNIGHTPOST;
  3093.       if (wstrong)
  3094.           Mknight[white][sq] += KNIGHTSTRONG;
  3095.       if (bstrong)
  3096.           Mknight[black][sq] += KNIGHTSTRONG;
  3097.       if (wstrong)
  3098.           Mbishop[white][sq] += BISHOPSTRONG;
  3099.       if (bstrong)
  3100.           Mbishop[black][sq] += BISHOPSTRONG;
  3101.  
  3102.       if (HasBishop[white] == 2)
  3103.           Mbishop[white][sq] += 8;
  3104.       if (HasBishop[black] == 2)
  3105.           Mbishop[black][sq] += 8;
  3106.       if (HasKnight[white] == 2)
  3107.           Mknight[white][sq] += 5;
  3108.       if (HasKnight[black] == 2)
  3109.           Mknight[black][sq] += 5;
  3110.  
  3111.       Kfield[white][sq] = Kfield[black][sq] = 0;
  3112.       if (distance (sq, wking) == 1)
  3113.           Kfield[black][sq] = KATAK;
  3114.       if (distance (sq, bking) == 1)
  3115.           Kfield[white][sq] = KATAK;
  3116.       Pd = 0;
  3117.       for (k = 0; k <= PieceCnt[white]; k++)
  3118.         {
  3119.         i = PieceList[white][k];
  3120.         if (board[i] == pawn)
  3121.           {
  3122.               pp = true;
  3123.               z = i + ((row (i) == 6) ? 8 : 16);
  3124.               for (j = i + 8; j < 64; j += 8)
  3125.               if (Patak (black, j) || board[j] == pawn)
  3126.                 {
  3127.                 pp = false;
  3128.                 break;
  3129.                 }
  3130.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  3131.           }
  3132.         }
  3133.       for (k = 0; k <= PieceCnt[black]; k++)
  3134.         {
  3135.         i = PieceList[black][k];
  3136.         if (board[i] == pawn)
  3137.           {
  3138.               pp = true;
  3139.               z = i - ((row (i) == 1) ? 8 : 16);
  3140.               for (j = i - 8; j >= 0; j -= 8)
  3141.               if (Patak (white, j) || board[j] == pawn)
  3142.                 {
  3143.                 pp = false;
  3144.                 break;
  3145.                 }
  3146.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  3147.           }
  3148.         }
  3149.       if (Pd != 0)
  3150.         {
  3151.         val = (Pd * stage2) / 10;
  3152.         Mking[white][sq] -= val;
  3153.         Mking[black][sq] -= val;
  3154.         }
  3155.       }
  3156. }
  3157.  
  3158. void
  3159. UpdateWeights (void)
  3160.  
  3161. /*
  3162.  * If material balance has changed, determine the values for the positional
  3163.  * evaluation terms.
  3164.  */
  3165.  
  3166. {
  3167.     register short s1;
  3168.  
  3169.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  3170.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  3171.     tmtl = emtl[white] + emtl[black];
  3172.     s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  3173.     if (s1 != stage)
  3174.       {
  3175.       stage = s1;
  3176.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  3177.       PEDRNK2B = -15;    /* centre pawn on 2nd rank & blocked */
  3178.       PBLOK = -4;        /* blocked backward pawn */
  3179.       PDOUBLED = -14;    /* doubled pawn */
  3180.       PWEAKH = -4;        /* weak pawn on half open file */
  3181.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  3182.       PADVNCM = 10;        /* advanced pawn multiplier */
  3183.       PADVNCI = 7;        /* muliplier for isolated pawn */
  3184.       PawnBonus = stage;
  3185.  
  3186.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  3187.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  3188.  
  3189.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  3190.       BishopBonus = BBONUS * stage;
  3191.  
  3192.       RHOPN = 10;        /* rook on half open file */
  3193.       RHOPNX = 4;
  3194.       RookBonus = RBONUS * stage;
  3195.  
  3196.       XRAY = 8;        /* Xray attack on piece */
  3197.       PINVAL = 10;        /* Pin */
  3198.  
  3199.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  3200.       KHOPNX = KHOPN / 2;
  3201.       KCASTLD = 10 - stage;
  3202.       KMOVD = -40 / (stage + 1);    /* king moved before castling */
  3203.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  3204.       KSFTY = ((stage < 8) ? (KINGSAFETY - 4 * stage) : 0);
  3205.  
  3206.       ATAKD = -6;        /* defender > attacker */
  3207.       HUNGP = -12;        /* each hung piece */
  3208.       HUNGX = -18;        /* extra for >1 hung piece */
  3209.       }
  3210. }
  3211.  
  3212. #endif // realold eval